Problem/Motivation
First reported at #2866736: JSON API should reply with a 409 status when sending a POST request to an existing entity for the JSON API contrib module.
Also see https://httpstatuses.com/409
Proposed resolution
Return a 409 for POST requests to an existing resource.
Remaining tasks
Make it work.
User interface changes
None.
API changes
None.
Data model changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #30 | 2870649-30.patch | 4.28 KB | jhedstrom |
| #30 | interdiff-2870649-28-30.txt | 787 bytes | jhedstrom |
| #28 | 2870649-28.patch | 4.24 KB | jhedstrom |
| #22 | 2870649-21.patch | 4.98 KB | wim leers |
| #22 | interdiff.txt | 961 bytes | wim leers |
Comments
Comment #2
wim leersThe goal is to make this test pass.
Comment #4
dawehnerLet's see whether this is it.
Comment #6
dawehnerNote: I do believe the test is in the wrong place. It should be after assigning the permission.
This doesn't fix the problem yet though.
Comment #7
wim leersI think that this cannot be implemented in
EntityResource::post(). Because the 409 must be thrown whenPOSTing to/node/1, not whenPOSTing to/node. But for the/node/1URL, onlyGET,PATCHandDELETEroutes exist.Therefore I think the only way to implement this is via a
\Drupal\Core\Routing\RoutingEvents::ALTERevent subscriber, which modifies all RESTGETroutes to also acceptPOSTand then adding a route filter that explicitly detects this case ("POSTing to aGET-only route") and then throws a 409 error response exception.If I'm right, then this is ridiculously convoluted, and probably not worth it…
Comment #8
dawehnerYou are absolutely right.
It is again a tradeoff of features vs. maintainablity. Maybe it would be worth to have these kind of things in contrib, but yeah I agree its tricky.
Comment #9
dawehnerMaybe we could just go with the following ...
Comment #10
wim leersThat's very clever! :)
So let's add back the test coverage I wrote in #2, to verify that this is working as intended.
Comment #11
wim leers#10 is failing because of a tiny bug in #9.
But then there is another problem: because the "GET" route now also supports the "POST" method, an important assertion that was added in #2775479: Try to remove the "map HEAD to GET" logic in \Drupal\rest\RequestHandler::handle() no longer holds true.
This should be green!
Comment #12
wim leersAnd clearly this patch is blocked on #2720233: Use arguments resolver in RequestHandler to have consistent parameter ordering: it needs the improvements there, otherwise this can't work:
Comment #13
wim leersThis will also need a change record to inform developers that this is now supported.
Comment #14
dawehnerThank you for using the right
$route:)This is one of those cases where doing things right, actually helps :)
Comment #15
wim leers:)
#11 wasn't green though! There are failures for all
ItemResourceTestBaseandEntityTestResourceTestBasetests (6 each), plus 2 failures inRequestHandlerTest.Also… while thinking some more about this yesterday evening, I realized this is not yet sufficient:
i.e. this is testing POSTing to
/node/5results in a failure. But what we want, is that POSTing to/noderesults in a failure, by checking whether theUniqueFieldconstraint has been violated!I guess that could be a follow-up, but it might be better to handle it here, because it's conceptually about the same thing. Perhaps our implementation becomes better because of it, because we'll be throwing a 409 HTTP exception from two places.
Comment #18
wim leersComment #19
dawehnerMaybe you just had some level of f.lux enabled on your laptop :)
Comment #20
wim leers#12 said this was blocked on #2720233: Use arguments resolver in RequestHandler to have consistent parameter ordering, but it hasn't been blocked on that for a long while, because that landed in September 2017!
Comment #21
wim leers#19: haha :P Thanks for bubbling this issue to the top again, it's how I noticed #20!
Comment #22
wim leersMost of this patch was committed in #2720233: Use arguments resolver in RequestHandler to have consistent parameter ordering. Which means this patch can become a lot smaller! 🎉
In the mean time, #2858482: Simplify REST routing: disallow requesting POST/PATCH in any format, make consistent got committed, which massively conflicted with this patch's changes in
ResourceBase. The attached interdiff is not really a diff. It shows the change we're making toResourceBaseas of this new patch.Comment #26
boby_ui commentedI have a problem with register api with d8, its randomly causing 409 error? what does this means? is it server configurations or?
Comment #27
jhedstromThis is a reroll of #22 against the latest 8.8.x.
Comment #28
jhedstromAttaching the patch would help :)
Comment #30
jhedstromThe reason a 403 instead of a 409 was happening in all those failed tests was that the test user didn't have access to view the entity in question, and that access check happens long before the 409 change in this patch. This gets tests passing by granting that access.
Comment #32
dhanlal commentedi working on this issue
Comment #33
dhanlal commented