fix(backend): default GET list endpoints to JSON per spec 6.2
Spec 6.2 says: 'Default JSON response wraps the same data in a
{items, total, returned, has_more} envelope so the frontend can
paginate uniformly.' Previously the GET list endpoints defaulted
to NDJSON (consistent with the parse endpoints), which forced
every curl call to set Accept: application/json.
Now NDJSON is strictly opt-in via Accept: application/x-ndjson;
JSON is the default. Parse endpoints keep their existing NDJSON
default (browser uploads).
T8 test 'test_claims_default_accept_returns_ndjson' updated to
assert the new default.
This commit is contained in:
@@ -143,21 +143,19 @@ def _client_wants_json(request: Request) -> bool:
|
|||||||
|
|
||||||
|
|
||||||
def _wants_ndjson(request: Request) -> bool:
|
def _wants_ndjson(request: Request) -> bool:
|
||||||
"""Content negotiation for list endpoints: NDJSON wins ties, NDJSON is the
|
"""Content negotiation for list endpoints: NDJSON is an opt-in, JSON is the
|
||||||
default when no Accept header is set (consistent with parse endpoints).
|
default (per spec 6.2: "Default JSON response wraps the same data in a
|
||||||
|
{items, total, returned, has_more} envelope so the frontend can paginate
|
||||||
|
uniformly").
|
||||||
|
|
||||||
Used by the GET list routes (/api/batches, /api/claims, /api/remittances,
|
Used by the GET list routes (/api/batches, /api/claims, /api/remittances,
|
||||||
/api/providers, /api/activity). When both ``application/x-ndjson`` and
|
/api/providers, /api/activity). NDJSON is returned only when the client
|
||||||
``application/json`` appear in Accept, NDJSON wins. When only JSON is
|
explicitly sends ``Accept: application/x-ndjson`` (with or without
|
||||||
asked for, JSON wins. When neither is asked for (e.g. browser default
|
``application/json``). Bare ``*/*``, an empty Accept, or an explicit
|
||||||
``*/*`` or an empty Accept), NDJSON wins.
|
``Accept: application/json`` all return the JSON envelope.
|
||||||
"""
|
"""
|
||||||
accept = request.headers.get("accept", "")
|
accept = request.headers.get("accept", "")
|
||||||
if "application/x-ndjson" in accept:
|
return "application/x-ndjson" in accept
|
||||||
return True
|
|
||||||
if "application/json" in accept:
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def _ndjson_stream_list(
|
def _ndjson_stream_list(
|
||||||
|
|||||||
@@ -278,7 +278,12 @@ def test_claims_ndjson_wins_over_json_when_both_accepted(seeded_store):
|
|||||||
assert resp.headers["content-type"].startswith("application/x-ndjson")
|
assert resp.headers["content-type"].startswith("application/x-ndjson")
|
||||||
|
|
||||||
|
|
||||||
def test_claims_default_accept_returns_ndjson(seeded_store):
|
def test_claims_default_accept_returns_json(seeded_store):
|
||||||
"""No Accept header → NDJSON (consistent with parse endpoints' default)."""
|
"""No Accept header → JSON envelope (per spec 6.2: JSON is the default for
|
||||||
|
list endpoints; NDJSON is the opt-in)."""
|
||||||
resp = seeded_store.get("/api/claims")
|
resp = seeded_store.get("/api/claims")
|
||||||
assert resp.headers["content-type"].startswith("application/x-ndjson")
|
body = resp.json()
|
||||||
|
assert "items" in body
|
||||||
|
assert "total" in body
|
||||||
|
assert "returned" in body
|
||||||
|
assert "has_more" in body
|
||||||
|
|||||||
Reference in New Issue
Block a user