Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
According to the JSON API specification, after creating an entity we should be adding a Location
header.
Proposed resolution
Add the header in the response for the EntityResource::createIndividual()
.
Comments
Comment #2
milopca CreditAttribution: milopca at Òmada Interactiva commentedComment #3
milopca CreditAttribution: milopca at Òmada Interactiva commentedPatch for adding Location in response headers.
Comment #6
e0ipsoThanks for the patch @milopca!
A very small nit pick:
Can we have the short version?
[]
instead ofarray()
Also:
Location
header matches theself
link in the JSON response?Comment #7
milopca CreditAttribution: milopca at Òmada Interactiva commentedFix the broken test and change array to the small version []
Test for this path is still pending
Comment #8
e0ipsoKicking the testbot.
Comment #9
milopca CreditAttribution: milopca at Òmada Interactiva commentedComment #10
e0ipsoIt seems that this patch is not adding the header after creating the entity. This is not a novice patch, cleaning up tags.
Comment #11
SpleshkaI believe that JSON API specification compliance issue should be resolved. Attached the patch with test.
Comment #12
e0ipsoThanks @Spleshka for rejoining this effort.
Comment #13
SpleshkaMy pleasure. FIY: tests failed because of the issue not related to the patch.
Comment #15
SpleshkaThe further progress is blocked by #2877589: Fix failing test in the dev branch, because tests fail.
Comment #16
SpleshkaThe blocker is cleared now, submitting the patch for re-testing.
Comment #17
SpleshkaNow all tests pass, awaiting for manual review.
Comment #18
e0ipsoThis looks good! Merging.
Comment #20
Wim LeersThis patch is incorrect, because it's not taking into account the fact that not every entity type has a
canonical
URL.See #2853211: EntityResource::post() incorrectly assumes that every entity type has a canonical URL for Drupal core.
Comment #21
SpleshkaVery good point, thanks @Wim. I'll provide a new patch.
Comment #22
clemens.tolboom(my 2 cents)
Weird as this committed patch give a location to http://drupal.d8/node/16 but the redirection resolves to the expected application/vnd.api+json response.
Fetch that location manually breaks of course
curl --header 'Accept: application/vnd.api+json' --request GET http://drupal.d8/node/16
Not sure what this means.
Comment #23
SpleshkaYet another good point, thanks @clemens.tolboom. Trying to bring all points together:
1. I assume that when an entity doesn't have a canonical URL we should not send Location header. However, specification explicitly says:
The response SHOULD include a Location header identifying the location of the newly created resource.
Probably empty Location header doesn't make sense here, as it might bring some confusion into DX. Any other suggestions?
2. Very good question in #22. Specification says that Location should identify the location of the newly created resource. The correct Drupal location is entity's canonical URL, which doesn't give any value for frontend apps using JSON API. So I suppose we should provide JSONAPI-friendly url to fetch an entity. It sort of kills issue #1 above (because there is no need to check for canonical url), but potentially brings in additional permission check to view the entity (or no need?).
3. From the resource POSTing specification:
This confirms my assumption in #3 - Location URL should match ['links']['self'], which currently provides json api-friendly endpoint to fetch the resource.
Any comments / notes before I move on with the implementation?
Comment #24
e0ipsoAh yes! Sorry, I should not have committed that patch. Late commits are never advisable :P
What I should have said there (and did in Dublin initially and forgot later) is that we want the resource entity link. Not the canonical entity link.
We have a link manager service that should help with the task.
Thanks Wim for reopening, and everyone for your contributions so far. In any case, I do not regret giving @Spleshka a commit after the fantastic work he's doing with the module :-D even if I jumped the gun.
Comment #25
SpleshkaYeah, thanks everyone for the feedback! Attaching the patch for the most thorough review ever :P
Comment #27
SpleshkaUpdated dependent tests as well.
Comment #28
e0ipsoI'm wondering what happens if we drop the entity repository…
Comment #30
SpleshkaActually nothing bad will happen :) I was going to create a follow up to get rid of it after this issue is done, to avoid patch conflicts. But we can get rid of it right now as well if you want.
Comment #31
SpleshkaOh, it's already done :) thanks a lot Mateu and other guys for getting this issue resolved.
Comment #32
e0ipsoFinally fixed! Thanks everyone.
Comment #33
Wim LeersNote that this is exactly why I argued a long time ago that the JSON API module should offer new link relation types. Then this could would have been far more elegant, and this mistake would likely have been prevented.
That can still happen at a later time of course.
Finally, test coverage is far too weak here. This should have a hardcoded relative URL, then the problem would have been obvious. Furthermore, there is no test coverage for entity types without a canonical URL: in core REST there would not be a Location response header, but for JSON API there would be.
All things that could (and should!) be addressed later.
Comment #34
e0ipso1. Can we have a follow up ticket to capture that? I agree it can be interesting the have Drupal-entities aware of the link to their JSON-API-resource-entity equivalent.
2. I'm not sure I agree 100%. We want the Location to be the same as the self link by design. The self link is tested agains a hardcoded string elsewhere (some of them anyways).
3. Not sure I understand.
Comment #35
Wim Leers1. I brought this up in #2829746: Clean up \Drupal\jsonapi\LinkManager\LinkManager(Interface) before, but that's been closed since.
2. Yep, we do want it to match the JSON API
self
link. Maybe that's tested against a hardcoded URL somewhere. But in the patches committed here, that was definitely not the case. Otherwise this bug would never have been introduced, because the problem would've been obvious. That's the value of seeing hardcoded strings in your test expectations.3. Imagine that entity type
foo
does not have a canonical URL. That meanshttps://d8/foo/5
does not exist. Buthttps://d8/jsonapi/foo/5
will exist, because JSON API generates a "individual JSON API resource" URL for every entity, even if it's an entity of an entity type with nocanonical
link relation type.Comment #36
e0ipsoWRT 1. We have now #2878463: [PP-1] Define a JSON API link relation for entities.
WRT 2. That's a good point. It would have been easier to spot. However testing absolute links is not super easy (b/c base_url differences, url prefix variations, …). In any case we could do regular expression matching. Feel free to create a new issue if you feel preg_match is a good way to test this. How are you testing them in REST core?
WRT 3. I understand the link situation. I don't understand the reference to lack of test coverage. Is there any action item we should capture here?