feat: add JSON:API content negotiation support for REST endpoints#148
feat: add JSON:API content negotiation support for REST endpoints#148teethaking wants to merge 1 commit into
Conversation
- Create src/middleware/jsonapi.ts middleware for Accept header transformation - Transform responses for transfers, summary, assets, and NFT endpoints - Add comprehensive unit and integration tests - Document JSON:API format in README with examples
|
@teethaking Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Miracle656
left a comment
There was a problem hiding this comment.
Nice approach — the content negotiation is correctly opt-in (a non-application/vnd.api+json Accept passes through untouched, and you have a test for it). But it doesn't compile:
src/middleware/jsonapi.ts(201,5): error TS2741: Property 'data' is missing in type
'{ errors: JsonApiError[] }' but required in type 'JsonApiResponse'
The error branch returns { errors: [...] } with no data, but JsonApiResponse declares data as required (line 27). Per JSON:API, data and errors are mutually exclusive, so the type should reflect that. Simplest fix — make data optional:
type JsonApiResponse = {
data?: JsonApiResource | JsonApiResource[] | null; // was: data: ...
meta?: Record<string, unknown>;
links?: Record<string, string>;
errors?: JsonApiError[];
};Please apply that and confirm npm run build (tsc) is green locally — the fork CI doesn't run the typecheck job, so it wasn't caught automatically. One more thing: this PR also now conflicts with src/api.ts since #149/#150 merged (both add routers there) — a quick git rebase origin/main will pick those up. Then I'll re-review.
Summary
Adds support for
Accept: application/vnd.api+jsoncontent negotiation, allowing clients to request JSON:API-shaped responses from major endpoints — the convention preferred by enterprise integrators — without changing the default response shape for existing consumers.Closes #135
What changed
src/middleware/jsonapi.ts(new)AcceptheaderAccept: application/vnd.api+jsonis present, transforms the standard response payload into a JSON:API-compliant document:dataenvelope withtype,id, andattributesrelationshipskey per the JSON:API specContent-Typetoapplication/vnd.api+jsonapplication/json), the existing response shape is returned unchanged — fully backward compatibleDocumentation
Acceptheader and resulting response shapeHow to verify
Accept: application/vnd.api+jsonand assert the response is JSON:API-shaped (data,type,id,attributes)Acceptheader (orapplication/json) and assert the original response shape is unchangedContent-Type: application/vnd.api+jsonis set on negotiated responsesChecklist
src/middleware/jsonapi.tsimplements content negotiation based onAcceptheaderContent-Typecorrectly set when JSON:API is negotiated