6.1 The query service: stored queries authored like files

A store can list and page, but it can't filter by field (4.4). The query service fills that gap: you author stored, parameterized queries and execute them over your data. Queries are authored like files — no tenant-config round trip — and run on any HTTP verb.

Mounting it

{ "path": "/q", "service": "query",
  "config": { "access": { "write": "A" } } }

Two surfaces: authoring and execution

A query mount has two faces, which is the store-view pattern (3.4):

  • Authoring — a reserved subtree, /<mount>/.queries/…, that obeys the full store contract (PUT/GET/DELETE, listings, ETags). This is where query specs live. Guard authoring with write (e.g. write: "A").
  • Execution — every other path under the mount, on any verb, runs the longest-prefix-matched stored query.

So you PUT a query spec to .queries/open-orders, then run it with GET /q/open-orders?status=open. Authoring and running are different paths, so a query can serve a plain GET to ordinary clients while only admins can edit it.

A query spec (the envelope)

{ "language": "json",
  "query": { "dataset": "orders",
             "where": { "status": "${status}",
                        "total": { "op": ">=", "value": "${min}" } },
             "orderBy": "total" },
  "params": { "type": "object", "required": ["status"],
              "properties": { "status": { "type": "string" },
                              "min":    { "type": "number", "default": 0 } } },
  "output": { "type": "array" } }
  • query — the query itself, in the backing language (here the reference adapter's JSON form).
  • params — a JSON Schema for the inputs: types, required, and defaults.
  • output — describes the result shape (surfaced on the agent surface).
  • language — optional; inferred (json for a JSON template, sql for a string template).

The envelope is validated at PUT time — a bad envelope or a non-compiling param schema is a 400 at write, not a surprise at execution.

The reference adapter

Out of the box, a JSON query runs against a data dataset via the reference adapter: where clauses AND together, field names may be dot-paths, ops are == (default) != < > <= >= contains, orderBy sorts, and each row gains a _key. Results come back as a JSON array with X-Total-Count, pageable with $take/$skip.

The backing language is pluggable (QueryStore capability): the same envelope shape can drive Mongo aggregates, an Elastic DSL, or a SQL adapter (6.4).

The next sections cover how parameters get in, and how the two template kinds (JSON vs. string/SQL) substitute them safely.


Part 5 — Auth & Access Control · Manual home · Next: 6.2 Parameters →