Skip to content

Commit 1ee7b9d

Browse files
committed
fix(api): POST returns no body when no representation was requested
PostgREST answers an insert without `Prefer: return=representation` with 201, an empty body and no Content-Type — `return=minimal` is "the default mode for all write requests", and its own suite asserts `shouldRespondWith ""` with matchHeaderAbsent hContentType. We answered 201 with the affected-row count as a JSON body. That is both non-standard and redundant: the count already travels in Content-Range via SetResponseHeaders on the line above. It also breaks the invariant a PostgREST client is entitled to assume — "a 2xx write returns a body only if I asked for one" — and a client that trusts it will try to read rows out of a bare number. Concretely: ragui types insertRecords as Result<any[]> and would hold the number 1, surviving today only because both call sites happen to guard with `r.data?.[0]`, which then misreports a successful write as "the record may have been deleted". PATCH and DELETE already returned 204 with no body and were conformant; POST was the only deviation. Verified with the assertions enabled by the previous commit: 12 ported cases across 8 endpoints failed before this change, 0 after, with the whole suite (database, api, postgrest, recursive) green. Still deviating, not fixed here: POST /rpc/<void function> returns 200 with body `null` where PostgREST returns 204, no content, no Content-Type (its test at rpc_test.go:962 is commented out, so this has never had coverage). It is not the same one-line change — ret_void and a null-valued ret_null both serialize to `null`, and PostgREST keeps 200 + `null` for the latter, so the handler needs the function's declared return type rather than its value to tell them apart.
1 parent 6834e48 commit 1ee7b9d

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

api/sources.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,13 @@ func InitSourcesRouter(apiHelper Helper) {
5353
if err == nil {
5454
SetResponseHeaders(c, w, r, count)
5555
if data == nil {
56-
return heligo.WriteJSON(w, http.StatusCreated, count)
56+
// No representation requested (the default, `return=minimal`):
57+
// PostgREST answers 201 with no body and no Content-Type, so a
58+
// client can rely on "2xx write => body only if I asked for it".
59+
// We used to write the affected-row count here, which is both
60+
// non-standard and redundant — the count already travels in
61+
// Content-Range via SetResponseHeaders above.
62+
return heligo.WriteHeader(w, http.StatusCreated)
5763
} else {
5864
return WriteContent(c, w, http.StatusCreated, data)
5965
}

0 commit comments

Comments
 (0)