Skip to content

Commit cc48091

Browse files
committed
docs(rest): record the #8039 ruling on DATA_RECORD_READ_PARAMS
The docblock above DATA_RECORD_READ_PARAMS (GET /data/:object/:id's closed query-parameter set) described the fields/populate alias-table spellings as an open question tracked by #8039. Maintainer ruling, 2026-08-12, settled it: option 2 - keep the narrow select/expand set, refuse the alias spellings loudly instead of folding them. Option 1 (folding RPC_QUERY_ALIAS_SLOTS onto this one route) was explicitly rejected as surface expansion with no measured pull, and would leave other data routes' ingress inconsistent in the opposite direction. No code change. refuseUnknownQueryParams(req, res, DATA_RECORD_READ_PARAMS) already refuses `?fields=` / `?populate=` with a located 400 VALIDATION_ERROR - measured directly against origin/main before this commit by running rest-server-closed-query-params.test.ts (27/27 passing), including the two cases that drive both spellings through the real by-id handler and assert the refusal plus that getData is never called. The behavioural half of the ruling was already shipped; this commit is the prose half the ruling asked for. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01P7vaLs7bhBPi9m3JyzkhDj
1 parent d2d6e4c commit cc48091

2 files changed

Lines changed: 58 additions & 11 deletions

File tree

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
"@objectstack/rest": patch
3+
---
4+
5+
docs(rest): record the #8039 ruling on `GET /data/:object/:id`'s query-parameter set —
6+
`fields` / `populate` are refused BY DESIGN, not an open question (#8039)
7+
8+
Documentation only — `refuseUnknownQueryParams` already rejects any input the same way
9+
it did before this change.
10+
11+
The route accepts exactly `select` / `expand`. It never folds the spec's alias table
12+
(`RPC_QUERY_ALIAS_SLOTS`, which maps `fields` → alias `select` and `expand` → alias
13+
`populate`), so the canonical `fields` spelling and the `populate` alias are outside the
14+
accepted set and refused with a located `400 VALIDATION_ERROR` naming `select` / `expand`
15+
as what the route accepts — never silently dropped.
16+
17+
That gap used to be recorded as an open question ("tracked as #8039 … rather than widened
18+
here"). It is now settled: maintainer ruling, 2026-08-12, took **option 2** — keep the
19+
narrow set, refuse the alias-table spellings loudly. **Option 1 (folding
20+
`RPC_QUERY_ALIAS_SLOTS` onto this one route, so `fields` / `populate` start working here
21+
too) was explicitly rejected** — it would be surface expansion on a public route with no
22+
measured pull behind it, and doing it for this route alone would leave every other data
23+
route's ingress inconsistent in the opposite direction. If the alias table is ever
24+
declared universal across data routes, that lands as one card applying the fold to ALL
25+
data routes at once, with its own ruling — never a quiet per-route widening.
26+
27+
For anyone integrating against this route: `?fields=…` and `?populate=…` are not aliases
28+
here and will not become one without a separate, wider decision. Use `select` / `expand`.

packages/rest/src/rest-server.ts

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,17 +1524,36 @@ export const APPROVAL_REQUEST_LIST_PARAMS: readonly string[] = [
15241524
* so every other parameter on this route is dropped in the fullest sense: it
15251525
* never reaches `getData` at all.
15261526
*
1527-
* ⚠️ The dropped names include the CANONICAL spelling of one slot. The spec's
1528-
* alias table (`RPC_QUERY_ALIAS_SLOTS`) declares the fields slot as canonical
1529-
* `fields` with alias `select`, and the expand slot as canonical `expand` with
1530-
* alias `populate` — but this route folds no aliases, so `?fields=name`
1531-
* silently returns the FULL record and `?populate=…` silently expands nothing.
1532-
* Both are outside this set on purpose: adding them here would advertise a
1533-
* capability the handler does not implement, which is the declared-≠-enforced
1534-
* trap in the other direction. Refusing them instead makes the gap
1535-
* self-reporting — the located message names `select` / `expand` as what this
1536-
* route does accept. Tracked as #8039 (an alias-coverage question for the spec
1537-
* table and this handler to settle together) rather than widened here.
1527+
* ⚠️ The accepted names deliberately EXCLUDE the CANONICAL spelling of one
1528+
* slot. The spec's alias table (`RPC_QUERY_ALIAS_SLOTS`) declares the fields
1529+
* slot as canonical `fields` with alias `select`, and the expand slot as
1530+
* canonical `expand` with alias `populate` — but this route folds no aliases,
1531+
* so `fields` / `populate` are not synonyms for anything this handler reads.
1532+
* Putting them in the allowlist unfolded would advertise a capability the
1533+
* handler does not implement — the declared-≠-enforced trap in the other
1534+
* direction, and strictly worse than refusing them: a caller sending
1535+
* `?fields=title` would pass recognition, then silently get back the FULL
1536+
* record because nothing downstream of the gate consumes the name. Refusing
1537+
* them instead makes the gap self-reporting — the located `400` names
1538+
* `select` / `expand` as what this route accepts.
1539+
*
1540+
* **[#8039] Settled by maintainer ruling, 2026-08-12 — record, not an open
1541+
* question.** Three shapes were on the table for the mismatch between this
1542+
* route's two names and the spec's alias table: (1) fold
1543+
* `RPC_QUERY_ALIAS_SLOTS` onto this route, so `fields` / `populate` start
1544+
* working here too; (2) keep this narrow set, but refuse the alias-table
1545+
* spellings loudly instead of dropping them; (3) keep + document as-is. The
1546+
* ruling took **option 2**, which is exactly what `refuseUnknownQueryParams`
1547+
* below already does — `fields` and `populate` are refused the same way any
1548+
* other unrecognised name is, naming `select` / `expand` as the accepted
1549+
* pair. ⛔ **Option 1 was explicitly rejected** and stays rejected here:
1550+
* folding the alias table onto this ONE route is surface expansion on a
1551+
* public route with no measured pull behind it, and doing it for this route
1552+
* alone would leave every other data route's ingress inconsistent in the
1553+
* opposite direction. The only thing that changes this: a ruling that
1554+
* declares `RPC_QUERY_ALIAS_SLOTS` universal across ALL data routes, landed
1555+
* as one card applying the fold everywhere at once — never a quiet widening
1556+
* of this route's set in isolation.
15381557
*/
15391558
export const DATA_RECORD_READ_PARAMS: readonly string[] = ['select', 'expand'];
15401559

0 commit comments

Comments
 (0)