UnderscoreParameters behaviour with GET requests
Hi all! I've noticed that when calling an endpoint, the UnderscoreParameters applies the transformation only if the Content-Type header of the request is set to application/vnd.api+json, which makes sense in POST, PUT, PATCH and whenever there is an actual body associated to the request.
However, GET requests usually do not have a body, and thus, it seems a bit odd to add the Content-Type header to the request just to have the query parameters underscores (e.g. filters). In fact, all jsonapi.org examples (see here) only set the Accept header.
I'm opening this issue to ask you what you think about the behaviour, and whether this is something you thought of explicitly.
Adding a Content-Type to the request fixes the problem and is a pretty straight-forward, but maybe we can find other solutions which may be more elegant and compliant to the JSONAPI specitication.
A possible solution I was thinking of is to apply the underscoring either if the Content-Type matches JSONAPI's mime type OR if there is no body and the Accept header matches JSONAPI's mime type. Of course this is just an idea, maybe there's something even better, or we can just leave the current implementation as-is.
What do you think?
Thank you!
Howdy @CostantiniMatteo :wave: This is a great catch. I cannot speak for the other maintainers but I suspect this was not intentional and may have been overlooked.
Your proposal for Accept seems reasonable here. I even wonder if we need to check for the body or whether checking Content-Type and falling back to Accept would be sufficient.
If I read the JSONAPI spec correctly, clients MUST send all requests with content-type: application/vnd.api+json.
The accept header is used for content negotiation of the response content-type, while processing request parameters is related to the request content-type. I think current behaviour is actually correct, the examples are showing a client sending an accept header because it expects an application/vnd.api+json response content-type, but it is not required to do so.
The normative part of the JSONAPI spec about content negotiation lists the requirements for clients and servers.
The Content Negotiation section in the spec is -- at least to me -- a bit ambiguous as it refers to "data in request documents":
Clients MUST send all JSON:API data in request documents with the header Content-Type: application/vnd.api+json without any media type parameters.
Does this also include query string parameters? I may be missing some formal definition of data and document in the HTTP context here.
It still seems odd, though, that any request without parameters (or request with parameters that do not require underscoring) work as one would expect, and instead "break" as soon a "dashed" parameter is included.
I don't know whether the current implementation is correct, but it may be worth discussing it. Maybe we can find a solution to the inconsistent behaviour?
@jeregrine what are your thoughts here?
So here is what I have learned. I think the proposal by @CostantiniMatteo is sound.
The Content-Type header req only applies when data is sent in a request document. If no request document (GET or DELETE requests), then the header Content-Type: application/vnd.api+json does not need to be applied. application/vnd.api+json MUST appear in the Accept header though, telling the client will accept a response doc of this type.
Also a GET request with a non-simple content-type will result in a preflight request. One consequence of adding the Content-Type header on GET (where perhaps you used to not) is the backend server might not expect this and won't return the right Accept-Control-Allow-Origin header.