Closed (fixed)
Project:
JSON:API
Version:
8.x-2.x-dev
Component:
Code
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Reporter:
Created:
20 Jul 2018 at 18:38 UTC
Updated:
30 Aug 2018 at 15:39 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
gabesulliceWhoa. When/how did this ever work? Of course the $request object doesn't have that attribute
Comment #3
wim leersI just thought of https://www.drupal.org/node/2954953 … because that involved landing #2854543: NegotiationMiddleware calls $request->setRequestFormat('html') when there is no _format request parameter, but shouldn't, which was originally created for JSON API: for #2831137: Remove the need for ?_format=api_json: assume the use of the 'api_json' format for routes managed by JSON API, the issue that made the patch above possible at all!
Now that #2854543: NegotiationMiddleware calls $request->setRequestFormat('html') when there is no _format request parameter, but shouldn't is in, I think much of #2831137: Remove the need for ?_format=api_json: assume the use of the 'api_json' format for routes managed by JSON API is now obsolete? Needs investigating.
Comment #4
wim leersYep … thanks to #2854543: NegotiationMiddleware calls $request->setRequestFormat('html') when there is no _format request parameter, but shouldn't having landed, we can just set the
_formatroute requirement on all JSON API routes toapi_json, and\Drupal\Core\Routing\RequestFormatRouteFilterwill automatically select it!#2854543: NegotiationMiddleware calls $request->setRequestFormat('html') when there is no _format request parameter, but shouldn't was a critical bugfix in https://www.drupal.org/project/drupal/releases/8.5.4. The 2.x branch already requires Drupal 8.5. I think it's reasonable to bump that to 8.5.4.
So much complexity … gone! 💀
Also, this makes JSON API more consistent: 404s previously would not have resulted in a JSON API-formatted responses, now they are. The
Accept: application/vnd.api+jsonrequest header is now optional too! Better DX!I fixed a bug by mostly deleting code:
😀
Comment #6
wim leersLet's make this green!
This failed on the 415 response assertions. Because
\Drupal\Core\Routing\ContentTypeHeaderMatcher::filter()throws a 415 and the format hasn't been set. I think a 415 itself is a strong enough signal. A response with this status code is all that the JSON API spec requires anyway.Comment #7
wim leersd.o is drunk 🤡
Comment #8
wim leers#2949807: Spec Compliance: Error responses are missing the `jsonapi` top-level member and #2991389: Test coverage: relationship response cacheabiliity made changes that requires a change here too.
Comment #11
wim leersComment #13
wim leersD'oh.
Comment #14
e0ipsoThis is great 🎉🔥!
I see you're still iterating on tests. The code itself looks fantastic and is approved.
Let's make these tests pass and we can RTBC.
I am compelled to point out that the spec says MUST in here:
This is a great example where we say, the spec is there to make our life easier not harder. If it doesn't make sense, we should go against it (it was written by flawed humans, like us).
I will probably quote this example in other issues 😜
Comment #15
e0ipsoSorry, a race condition made the assignment change.
Comment #16
e0ipsoI think I'm missing something WRT tests. I am not sure why assertions are changing so much for this issue.
These are not asserting the same thing. I'm assuming this was a cosmetic change?
👏🏽
I'm unsure why we are losing these assertions and not the one on line 594.
We seem to be losing some additional assertions.
Comment #17
wim leers#14:
😀 Hurray!
Hah! 😀 I'm not sure which "MUST" you were referring to in the screenshot?
#16:
I explained that in #6.
api_json, since … no route was found, and hence the format never got set toapi_json.And hence the 404 response does not contain JSON, but HTML (the default).
api_jsonformat, is that it's a non-existing UUID on an actual JSON API route. The assertions in point 1 are 404s on a non-existing route. That's the difference!MethodFilter.I share your concerns. The only way to make this work then though is to still keep
FormatSetter…As explained in #3 and #4, thanks to #2854543: NegotiationMiddleware calls $request->setRequestFormat('html') when there is no _format request parameter, but shouldn't plus setting
requirements: [format: api_json]allows us to remove a lot of custom code. But there's one downside: 4xx exceptions thrown during routing do not result inapi_jsonresponses.So we have a choice to make here:
FormatSetter… but make it a little bit simplerComment #18
wim leersIf we choose 1, #13 is the patch.
If we choose 2, this is the patch (hopefully green on first try 🤞). No code removal, but best spec compliance, and still code simplification!
Comment #19
wim leersI actually prefer option 2 too. Fewer changes, more robust, stronger spec compliance.
I would have loved to do option 1, but alas, it comes with too many downsides.
Comment #20
e0ipsoI prefer option 2 as well. However, we explored that option years ago and run into dead ends:
/blog/jsonapiand expect HTML format.With all that in mind we resolved that the only acceptable way to know if we are dealing with a JSON API request is to check the matched route's metadata. That implies that errors that happen before matching routes will miss the format setter (404, route level 403).
What about requiring the Accept header? Did we reopen that debate?
Comment #21
wim leers/jsonapi/!\Drupal\Tests\jsonapi\Functional\JsonApiFunctionalMultilingualTest::testReadMultilingual()test coverage proves that multilingual "normal" JSON API responses do in fact work.So I think #18 actually already addresses 99% of your concerns?! :)
We haven't yet. But that would violate one of your primary principles AFAIK … because that'd mean going to
/jsonapiin your browser would NOT return JSON, but a HTML 4xx response…Comment #22
e0ipsoHmm, I don't agree with this. Many, many people use JSON API in multilingual decoupled apps. @dawehner and I worked on this in the past to make sure GETs were supported. Oddly enough no one ever asked about more than that when it comes to translations.
I don't think we should break what we have unless it's completely necessary and unavoidable. We could however (if we really wanted to) transition to a new content translation paradigm (force language negotiation based on
Accept-Languageheaders), and then revisit this. However, even then I don't think we should proceed because the realm negotiation APIs are still in effect for anyone to make use of them. By inspecting the URL like that we get a very small win compared with the damage it causes.Again, we considered this years ago and decided against, I think all of the reasons from back then are still valid today.
My opinion is let's go with #13 if we want to move this forward.
RTBCing #13 here. If you want to push for #18 we can set back to Needs Review and I'm happy to discuss further.
Comment #23
wim leersI'm … confused. I actually would like to do #13 too (because less code, less complexity), but I thought you actually disliked that more, based on your review in #16? And it comes with certain downsides that I explained in #17. So … yeah … I'm confused 🙃 😀
Moved this to #2794431-53: [META] Formalize translations support! 🙏
Comment #24
e0ipsoLOL, all in agreement for #13. Sorry for the confusion, my review in #16 was meant to be positive.
In any case, feel free to commit #13.
Comment #26
wim leersHeh, no problem 😁
That was a bit confusing indeed, which is why I did all that extra work to absolutely ensure that you agreed, and had the full set of choices available to you 🙏