From 2b0685b3c5bce486c4a3b37be71ee9b8069a5f87 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 8 Aug 2026 17:31:12 +0000 Subject: [PATCH] docs(runtime-services): document data.query() beside find on the services.data page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The page's own declared Canonical source (packages/client/src/index.ts) marks data.find @deprecated pointing at data.query(), which the page never mentioned. Add query to the Methods block in the source's declaration order, record the deprecation posture with attribution to the source (the same pattern the page already uses for the QueryOptions/QueryOptionsV2 vocabulary layer), document the Partial QueryAST parameter and the shared PaginatedResult envelope, and extend the example with a query call carrying nested expand detail — the shape find itself refuses with an error that points at query. Evidence for this direction over withdrawing the tag: query exists on both ObjectStackClient.data and ScopedProjectClient.data, ships untagged in dist/index.d.ts while find ships with the tag, is served by a dedicated POST /data/:object/query route, and is the recorded product direction (#986, commit 17dca1326). The docs page was the stale side. Fixes #6323 Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01F8q5J1MQyocgtNspb15fSn --- .../kernel/runtime-services/data-service.mdx | 51 +++++++++++++++++-- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/content/docs/kernel/runtime-services/data-service.mdx b/content/docs/kernel/runtime-services/data-service.mdx index 12950fcb0b..6e235acb8f 100644 --- a/content/docs/kernel/runtime-services/data-service.mdx +++ b/content/docs/kernel/runtime-services/data-service.mdx @@ -1,6 +1,6 @@ --- title: services.data -description: CRUD runtime helper API for records (`get`, `find`, `create`, `update`, `delete`). +description: CRUD runtime helper API for records (`query`, `get`, `find`, `create`, `update`, `delete`). --- # `services.data` @@ -32,13 +32,38 @@ the code that **holds** the binding calls it, with plain arguments and no `ctx` ## Methods ```ts -services.data.get(object: string, id: string): Promise> +services.data.query(object: string, query: Partial): Promise> services.data.find(object: string, options?: QueryOptions | QueryOptionsV2): Promise> +services.data.get(object: string, id: string): Promise> services.data.create(object: string, data: Partial): Promise> services.data.update(object: string, id: string, data: Partial): Promise> services.data.delete(object: string, id: string): Promise ``` +### Two list entries, one preference + +`query` and `find` both answer a list read with the same +`{ records, total?, hasMore? }` envelope, and the Canonical source declares which +of the two to prefer — the block above lists them in its declaration order. +`data.query` is *"Advanced Query using ObjectStack Query Protocol"*; `data.find` +carries an `@deprecated` tag in the same file: *"Use `data.query()` with standard +QueryAST parameters instead. This method uses legacy parameter names."* The tag +ships in the package's published type declarations, so an editor strikes `find` +through at every call site and points at `query`. As with the options vocabulary +below, the posture is the SDK's own, not this page's — it is recorded product +direction ([#986](https://github.com/objectstack-ai/objectstack/issues/986): +deprecate the legacy-parameter query entries, promote `data.query(AST)`). + +Deprecated means "prefer `query`", not "scheduled for removal in this version": +`find` remains fully functional, keeps both of its option vocabularies (see +[below](#find-options-canonical-and-legacy)), and the Canonical source still +names `QueryOptionsV2` *"the recommended interface for `data.find()` queries"* +for callers that stay on it. The capability line between the two entries is +real, though. `find` rides GET query parameters, so it has no spelling for a +`search` term or for nested `expand` detail — it refuses a nested expand with an +error whose own text says to use `data.query()`. `query` POSTs the full +`QueryAST` as a JSON body (`POST /data/:object/query`) and carries all of it. + ## Canonical source Every sibling page in this chapter names a contract interface @@ -60,6 +85,12 @@ key for key. A managed runtime binds `services.data` to this same shape. - `object`: short object name (for example `task`, `account`) - `id`: record ID for single-record operations - `data`: partial payload for create/update +- `query` (`query`): a `Partial` — the spec's query protocol shape + (`packages/spec/src/data/query.zod.ts`): `where` / `fields` / `orderBy` / + `limit` / `offset`, plus the AST-only clauses (`search`, `expand` with nested + detail, `aggregations`, `groupBy`, `having`). The AST's own `object` key is + not needed here: the server takes the target from the `object` argument (the + URL path) and overwrites anything the body says - `options` (`find`): filtering, sorting and pagination — two vocabularies, one behaviour; see the table below @@ -97,7 +128,8 @@ silently rather than refused, so migrate an options object as a whole. ## Returns - `get`: single record payload -- `find`: list payload + pagination metadata +- `query`/`find`: list payload + pagination metadata — the same + `PaginatedResult` envelope for both - `create`/`update`: mutated record payload - `delete`: `{ object, id, success }` — the spec's `DeleteDataResponse`. The flag is `success`, not `deleted` (#5638) @@ -133,7 +165,18 @@ export async function recentOrdersForContact(data: DataService, contactId: strin limit: 20, }); - return { contact, orders }; + // `query` — the Canonical source's preferred list entry — POSTs the same + // words as a Partial body, and carries the clauses `find` has no + // GET spelling for. Here: per-relation `expand` detail, which `find` + // refuses with an error that itself points at `query`. + const { records: withContact } = await data.query<{ id: string; amount: number }>('sales_order', { + where: { contact_id: contact.id }, + orderBy: [{ field: 'created_at', order: 'desc' }], + limit: 20, + expand: { contact_id: { object: 'contact', fields: ['name'] } }, + }); + + return { contact, orders, withContact }; } ```