Reference
Wire format (JSON)
The normative, language-independent JSON projection of QuerySpec.
Mirrored from
docs/spec/wire-format.md
(normative). Decision records: ADR-0001, ADR-0011. This is the JSON projection of QuerySpec
exchanged between clients, servers and the future Java port.
Shape
{
"filters": [
{ "kind": "condition", "field": "price", "op": "between", "value": [1000, 5000] },
{ "kind": "condition", "field": "category", "op": "in", "value": ["phone", "laptop"] },
{ "kind": "condition", "field": "deletedAt", "op": "isNull" }
],
"sorts": [
{ "field": "price", "direction": "desc", "priority": 1 },
{ "field": "stock", "direction": "asc", "nulls": "last", "priority": 2 }
],
"offset": 30,
"limit": 30
}Rules
filtersandsortsare always present (possibly[]). Optional members (limit,offset,cursor,version,nulls,value) are omitted when unset — nevernull.- Every filter node carries the
kinddiscriminator ("condition"|"group"). Missing/unknownkind⇒INVALID_VALUE. v0.1 engines reject"group"nodes with a structuredINVALID_VALUE(reserved for v0.3); the shape above never changes when groups unlock. - Field names are always internal schema names. String-format aliases never appear in JSON.
- Values are typed JSON — never coerced: numbers as finite JSON numbers, booleans as JSON
booleans, dates as ISO-8601 strings (
YYYY-MM-DDor datetime with mandatoryZ/offset), enum/custom values as strings."5"on a number field ⇒INVALID_VALUE. isNull/notNullconditions must not carry avaluemember.betweencarries a 2-element array;in/notIna non-empty array.direction∈"asc" | "desc",nulls∈"first" | "last",logic∈"and" | "or"— exact lowercase literals (Java maps enums with explicit wire names).priorityis an integer ≥ 1. Canonical producers emit contiguous1..n; consumers order by(priority, array index).limit/offsetare integers ≥ 0.offsetandcursorare mutually exclusive ⇒CONFLICTING_PAGINATION.versionis reserved for spec migrations; v0.1 accepts only1(or absent) and passes it through.- Root-level
filterscombine with AND (v0.1).
Result serialization
Errors serialize as { "code", "field"?, "op"?, "message", "position"? } inside
{ "ok": false, "errors": [...] }; success as { "ok": true, "value": ... }. message
wording is not normative (ADR-0003 §6).