Skip to content

CRUD endpoint POST response is a single-item list instead of an object - #338

Open
juneja-varun wants to merge 1 commit into
piccolo-orm:masterfrom
juneja-varun:fix/post-response-shape
Open

CRUD endpoint POST response is a single-item list instead of an object#338
juneja-varun wants to merge 1 commit into
piccolo-orm:masterfrom
juneja-varun:fix/post-response-shape

Conversation

@juneja-varun

Copy link
Copy Markdown

Closes #211

I POST to a PiccoloCRUD endpoint to create a resource and expect to read the new id straight off the parsed response, like response.json()["id"]. Instead the body comes back as a single-item list - [{"id": 4}] - so every client has to unwrap it first, which isn't how a REST API creating one resource should behave (and there's no way to POST multiple rows to this endpoint, so the list never has more or less than one item anyway).

The cause: row.save().run() on a new row does insert(self).returning(pk_column), which always returns a list (even for a single-row insert), and that list was being JSON-dumped directly. Two lines above, the BaseUser branch already does the right thing (dump_json({"id": user.id})), so this just brings the general-table branch in line with that existing pattern - unwrap the single item before dumping it, exactly as proposed in the issue itself.

Verified this doesn't silently change anything else that depends on the response shape: FastAPIWrapper's POST route declares response_model=self.ModelOut (a single object, not a list) for its Swagger schema - but since the underlying handler returns a raw Response object directly, FastAPI doesn't re-validate against that schema at runtime, so the actual response contradicted its own already-published schema before this fix. Grepped the rest of the codebase (including e2e tests and docs) for anything else parsing this response as a list - found and fixed one existing test (TestResponses.test_post in the FastAPI test suite) that had encoded the buggy shape as its expected value; updated it to match the corrected response.

Added a dedicated regression test confirming the response body is a dict (and that its id matches the actual inserted row), confirmed it fails on unpatched code with the exact [{'id': 1}] shape and passes with the fix. Full suite green (216 passed, 3 skipped), isort/black/flake8/mypy clean.

Worth flagging explicitly since it's a response-shape change: any existing client currently unwrapping a single-item list (response.json()[0]["id"]) would need to update to read response.json()["id"] directly after this lands - though that's exactly the shape the issue is asking for, and the shape already documented in ModelOut.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CRUD Endpoint POST response is a list

1 participant