Transform signature table.
Resource retrieval template.
Collection property projection.
Template value model.
Projection value model.
Property value template.
Atomic value template.
Localised text map template.
Union-typed property template.
Union branch key.
Constrained retrieval node.
Collection retrieval constraints.
Named computed expression.
Computed expression.
Transform pipe.
Property path.
Constraint option set.
Constraint option.
Sort order.
Parsed Criteria or Projection key.
Constraint operator symbols.
Value transforms for computed expressions.
Aggregate transform.
Static typing profile of a Transform.
A REST/JSON data model and a client-driven retrieval model for projection, filtering, and aggregation
Checks if a value is a Template.
Checks if a value is a Projection.
Checks if a value is a Slot.
Checks if a value is a Cell.
Checks if a value is a Placeholder.
Checks if a value is an Atomic.
Checks if a value is a Locale template.
Checks if a value is a Union.
Checks if a value is a Branch key.
Checks if a value is a Query over a given retrieval form.
Checks if a value is a Criteria.
Checks if an entry is a valid Criteria constraint.
Checks if a value is a Criteria constraint key.
Checks if a value is a Binding.
Checks if a value is an Expression.
Checks if a value is an Options set.
Checks if a value is an Option.
Checks if a value is an Order.
Checks if a value is a Probe.
Checks if a value is an Operator.
Checks if a value is a Transform.
Checks if a value is an Aggregate.
Resolves an Order to its sort precedence.
Resolves an Order to its sort direction.
Encodes a template as a JSON string.
Decodes a template from an encoded string.
Encodes criteria as a URL-safe string.
Decodes criteria from a URL-safe string.
Encodes a probe as a key string.
Decodes a probe from a key string.
Client-driven resource retrieval.
Defines types for specifying the data envelope to retrieve in REST/JSON APIs, including property projection, linked resource expansion, and, for collections, filtering, sorting, and pagination.
QEST's design rationale covers the client-driven retrieval approach; Appendix A covers cross-backend semantics and normalisation.
Retrieval model
Type guards
Accessors
Codecs
Retrieval Patterns
Resource Retrieval
A Template specifies which properties to retrieve from a single Resource and how deeply to expand linked resources. No over-fetching of unwanted fields, no under-fetching requiring additional calls:
Every request is an object and every leaf is
{}, the Atomic standing for the value as it comes: a literal, the reference of a linked resource left unexpanded, or the coalesced label of a localised property. A template carries no data of its own, so what a client writes is a pure statement of what it wants back. The empty request{}states nothing and brings back the server defaults.Collection Retrieval
A collection is reached through the resource that owns it, following REST/JSON practice, and is constrained there: the entry naming it carries the Criteria keys that filter, sort, and paginate it alongside the per-item keys. A single call retrieves filtered, sorted, and paginated results with arbitrarily deep expansions:
Cardinality is not stated by the notation: the same entry shape serves a single-valued and a multi-valued property, and which one a field names is settled by the model. Constraints are simply meaningless on a single-valued property and are rejected there.
Localised Properties
A localised property is retrieved in either of two ways. An Atomic yields its coalesced label, the plain string resolved under the request's negotiated language priority; a Locale map yields the tagged values structurally, as a Dictionary restricted to the locales its TagRange keys select:
The
TagRangekeys are RFC 4647 basic language ranges that filter which locales populate the map (the standalone*matches every tag, and a plain range such asenalso matches more specific tags likeen-US). Per-tag cardinality follows the property, not the template. Tag ranges select retrieved content only and are independent of Criteria: aLocalemap carriesTagRangekeys, never constraint keys. Resource matching by localised text is done separately, at the enclosing collection via?/!.The
@nonekey for non-localised values is not supported; use theundtag for language-neutral values.Computed Properties
Projections can define computed properties using expressions combining property paths with Transform.
Plain transforms operate on individual values and may project literals, linked resource references, nested templates expanding a linked resource inline, or Locale tag-range maps declaring a localised cell that yields a complete Dictionary value per row:
A projection emits distinct rows: rows with the same combination of cell values collapse into one, so the result is the set of distinct binding tuples rather than a multiset. Distinctness spans the whole collection, folding both multi-valued fan-out duplicates and equal tuples from different items; include an identifying binding such as
id(as above) to keep otherwise-equal items on separate rows.Aggregate Grouping
Aggregate transforms operate on sets of values. A collection is evaluated under grouped semantics when at least one Projection binding resolves to an aggregate Expression; otherwise it stays ungrouped, every item is projected on its own, and an aggregate constraint reduces over the values its path gathers from the item under evaluation, filtering, sorting, or ranking the items by that reduction.
Under grouped semantics, each operator's role is determined by whether its expression references an aggregate transform:
Grouping is fixed by the projection alone and is never inferred from a sort key: a non-aggregate ordering expression MUST reference an existing grouping key, and processors MUST reject one that matches none.
Rows sharing the same grouping-key values collapse into a single group. Aggregate filter and ordering constraints are independent of any projected bindings: an aggregate may appear in a constraint without being projected, and a projected aggregate may appear without being constrained.
Aggregate expressions use bag semantics over their inputs:
count:(empty path) returns the number of rows in scope; a non-empty path (for example,sum:price) ranges over the values resolved by the path for each input row, with multi-valued path fan-outs contributing every resolved value individually. No implicit deduplication is applied: clients needing distinct-value aggregates project the value of interest as a non-aggregate grouping binding.The ungrouped reduction states cardinality constraints over a plain template, retrieving the vendors carrying at least three products:
See Aggregate Transforms for the transform catalogue and cross-backend semantics.
Faceted Search
Aggregates enable faceted search patterns, computing category counts, value ranges, and totals in a single call:
Union Branches
For properties whose declared range is a union type, a Union declares per-branch retrieval by mapping opaque keys to the Placeholder to fetch for each variant of interest. The keys carry no positional or nominal meaning: the variant a placeholder retrieves is fixed by matching it against the property's declared variants, and an unmatched variant is skipped at runtime. Branch out only where the alternatives want different shapes; where one shape serves them all, a plain Placeholder addresses the property directly:
Expressions
A Projection Binding key pairs a result name with a computed value: a pipeline of Transform and a property path (together an Expression). The result name and its
=are mandatory; a bare identifier is not a binding:Value Ordering
Comparison (
<,>,<=,>=) and sort (^) operators rely on a total ordering over values defined by the XPath 2.0 comparison operators, which are in turn based on XSD ordered value spaces. These operators, along with sort focus (+), target Literal values only; Reference values, nested Template resources, and Dictionary values are neither comparable nor sortable:null— undefined values sort before all defined valuesboolean—false<truenumber— standard numeric ordering;NaNis unorderedstring— Unicode codepoint collationCross-type comparisons and values that fall outside these rules produce unpredictable, system-dependent results.
Result Typing
A template says what to retrieve, not what the retrieved values are: an Atomic leaf stands for whatever the property holds, so a template alone cannot tell a
stringproperty from anumberone. Result types come from the declared model instead. The keys a client writes and the keys it reads back differ too: Criteria constraints carry nothing back, and a Binding lands under its result name, the part before the=.Serialisation
Template Serialisation
Template objects are serialised as JSON via encodeTemplate / decodeTemplate, with IRI internalisation and resolution handled transparently. The encoder emits plain JSON by default and optionally URL-encoded JSON or URL-safe base64url-encoded JSON for transport; the decoder auto-detects the input encoding.
Criteria Serialisation
Criteria objects are serialised as application/x-www-form-urlencoded strings via encodeCriteria / decodeCriteria for transmission as URL query strings in GET requests.
Form serialisation carries constraints alone; servers are expected to convert to a collection template by merging them into the entry naming the target endpoint's collection property, alongside a default per-item retrieval template.
The format encodes queries as
label=valuepairs where:expression=valuefor?expression=value(disjunctive matching)expression<=valuefor<=expression=value(less than or equal)expression>=valuefor>=expression=value(greater than or equal)Values use JSON primitive syntax, with a Dictionary entry inlined through a single postfix
@tagsuffix:@tagsuffix, lifting it into a one-entry Dictionary (for example,"text"@endecodes to{ en: "text" })Encoding notes:
~(like),!(all)&(separator),=(key/value),+(space),%(escape)Numeric-looking values like
123are parsed as numbers unless double-quoted.This query:
categoryis "electronics" OR "home"namecontains "widget"priceis between 50 and 150 (inclusive)priceascending