Guides
Saved queries and recipes
Name a query or a set of writes once, then run it by name from anywhere, with typed parameters.
Saved queries
A saved query is the query grammar on one kind, stored by name, with {"$param": "<name>"} where the caller's value goes. It is checked when you save it, so a column it cannot read is refused now rather than later.
await db.saveQuery({
key: 'jobs_by_status',
label: 'Jobs in one status',
kind: 'job',
spec: { where: { status: { $param: 'status' } }, orderBy: [['created_at', 'desc']] },
params: [{ name: 'status', type: 'text', required: true }],
});
const { rows } = await db.run('jobs_by_status', { status: 'booked' });An optional parameter left out drops its condition. Saving the same key again replaces the query; db.archiveQuery(key) removes it, and db.queries() lists them.
Write recipes
A recipe is up to ten steps that run in one transaction, each writing a record or archiving one. {"$param": "<name>"} takes a caller's value and {"$step": "<as>"} the id an earlier step wrote.
await db.saveRecipe({
key: 'book_job',
label: 'Book a job for a customer',
params: [
{ name: 'customer', type: 'uuid', required: true },
{ name: 'title', type: 'text', required: true },
{ name: 'status', type: 'text', default: 'booked' },
],
steps: [
{ op: 'write_record', kind: 'job', as: 'job', data: { title: { $param: 'title' }, status: { $param: 'status' } }, links: { customer: { $param: 'customer' } } },
{ op: 'write_record', kind: 'message', data: { body: 'Booked in. We will confirm a time.' }, links: { job: { $step: 'job' } } },
],
});
const result = await db.call('book_job', { customer: contactId, title: 'Gutter clean' });
result.ids.job; // the id the first step wroteEvery step commits, or none does, and a refusal names the step and the field. A recipe call is never retried by the SDK, because a write that may have landed is not safe to send twice.
db.archiveRecipe(key) retires a recipe. It stops anyone running it, customers included; saving a recipe with the same key later brings it back.
A recipe can also be opened to a role of your app's people, so customers can run it themselves: see Let customers take an action.