6.5 Param schemas, defaults, and validation

The params block of a query envelope is a plain JSON Schema describing the query's inputs. It does three jobs: it types the inputs (so coercion works), it supplies defaults, and it validates — and it's also what the agent surface advertises so callers know how to invoke the query.

What params declares

"params": {
  "type": "object",
  "required": ["status"],
  "properties": {
    "status": { "type": "string" },
    "min":    { "type": "number", "default": 0 },
    "limit":  { "type": "integer", "default": 50 }
  }
}
  • type/properties — the parameter names and their types. Types drive the coercion of string-sourced values (URL segments, query strings) into numbers, integers, and booleans (6.2).
  • required — a missing required param is a hard 400 at execution.
  • default — applied for any param the caller omitted, before validation.

The execution order (recap)

  1. Collect raw values from URL segments, query string, and body (6.2).
  2. Coerce string-sourced values to declared types.
  3. Apply defaults for missing params.
  4. Validate the full set against params.
  5. Substitute (structurally for JSON, by binding for SQL) and run.

A failure at step 4 is 422 validation_failed with an errors array of {path, error}; a missing required param surfaces as 400. Either way the query does not run with bad inputs.

Validated at write and read

The param schema itself is compiled and checked when you PUT the query spec — a non-compiling schema is rejected at authoring time, not deferred to the first execution. So a stored query is always either valid-and-runnable or rejected; it can't sit in a half-broken state.

The agent surface reads it live

Stored queries appear on the agent surface (/.well-known/rs2/agent-surface, 9.1) with their params and output schemas, read live from the store. That means an API consumer — or an AI agent — can discover exactly how to call a query (which params, which types, which are required) without documentation drift: the schema enforced at runtime is the schema advertised.

Design tips

  • Give optional filters a sensible default, or pair them with the optional placeholder "${name?}" (6.3) so they vanish when unset.
  • Type numeric and boolean params precisely so plain links and forms work without JSON-encoding values.
  • Keep required minimal — every required param is a way for a caller to get a 400.

The final section of this part uses the same store-view idea to render HTML from request data. After that, Part 7 moves from reading data to composing services into multi-step flows.


Previous: 6.4 String/SQL templates · Manual home · Next: 6.6 Rendering HTML with templates →