API Platform version(s) affected: 2.5.0
Description
I followed this in the documentation https://api-platform.com/docs/core/content-negotiation/#configuring-error-formats
When receiving an Error response (eg: 404 Not Found), I always receive a JSON-LD response, not a JSON-PROBLEM although application/problem+json is configured right before application/ld+json in error_formats
Then if decide to use an Accept header with application/problem+json I receive this error
Requested format \"application/problem+json\" is not supported. Supported MIME types are \"application/ld+json\", \"application/json\", \"text/html\".
Adding jsonproblem: ['application/problem+json'] to formats solves this but what is the point of adding error_formats in this case? because it is ignored when used at the same time with application/ld+json
How to reproduce
The following api_platform configuration causes this issue:
api_platform:
....
formats:
jsonld: ['application/ld+json']
json: ['application/json']
html: ['text/html']
error_formats:
jsonproblem: ['application/problem+json']
jsonld: ['application/ld+json']
Possible Solution
In ApiPlatform\Core\EventListener\AddFormatListener maybe check also the error_formats listed in the configuration. If an Exception is thrown check the formats listed in error_formats and return a JSON representation (LD or Problem or whatever) based on the order they have been added in the configuration. For example if jsonproblem: ['application/problem+json'] is first in the list then use it prior to `jsonld: ['application/ld+json']
Additional Context
Thanks for your detailed report, would you be able to patch this and open a PR?
Is your request in JSON-LD / Hydra format, i.e. Accept: application/ld+json (or without Accept header since you've configured jsonld as the first format hence the default)? If so, it'll always return the error in Hydra format. This is by design and not a bug.
As I've explained to you on Slack, if you use Accept: application/json then you should get errors in application/problem+json format. If that's not the case, then that's a bug.
Even though this is by design that does not seem logic to me to have formats and error_formats in this case. Let's forget about any Accept header.
I just configure some formats so I put in this order application/ld+json, application/json. So application/ld+json has higher priority for any standard API responses. I understand that. But then I add formats under error_formats key in this order application/problem+json and application/ld+json.
I would expect from this, that when an exception is thrown, API platform check the formats listed under error_formats first not under formats. Or even better check the formats listed under formats first then see if under error_formats, there is a configuration overriding the one under formats. Then display the error using application/problem+json because it has higher priority under error_formats key. Otherwise that does not make sense to have such configuration available. So it still seems to me that it is a bug
@soyuka I can do it yes but as long as it is not recognized as a bug I cannot start working on it...
It may be a bit confusing, but the formats and error_formats configurations don't work the same way. 馃槃
The way I understand it, a Hydra response should always use the Hydra error format. That's not configurable, as it wouldn't make sense otherwise. Just like a JSON:API response should always use the JSON:API error format.
So @teohhanhui can you please explain clearly the purpose of error_formats? since it does not override anything
Basically, if the current format is also in error_formats, it'll always be used:
You can remove jsonld from error_formats if you want to prevent it from being used.
p/s: IMO Accept: application/problem+json makes no sense and should not be used.
Basically, if the current format is also in
error_formats, it'll always be used:You can remove
jsonldfromerror_formatsif you want to prevent it from being used.p/s: IMO
Accept: application/problem+jsonmakes no sense and should not be used.
I tried this:
formats:
jsonld: ['application/ld+json']
json: ['application/json']
html: ['text/html']
error_formats:
jsonproblem: ['application/json']
Ok it works, so you can only pass one format in error_formats ? I am asking because this link https://api-platform.com/docs/core/content-negotiation/#configuring-error-formats suggests that we could use multiple formats inside error_formats
From the documentation entry you've linked, it's already stated:
For instance, if a client request a JSON-LD representation of a resource, and an error occurs, then API Platform will serialize this error using the Hydra format (Hydra is a vocabulary for JSON-LD containing a standard representation of API errors).
so you can only pass one format in error_formats ?
No, you can provide more than one formats, but you must expect that an error format will be used if it matches the request format (see my comment above).
@teohhanhui
Ok that makes sense... let's us say we have
formats:
jsonld: ['application/ld+json']
json: ['application/json']
html: ['text/html']
error_formats:
jsonproblem: ['application/json']
jsonld: ['application/ld+json']
I tried and unless I send an Accept header with application/json I will always have response formatted as ld+json. So if I want only response errors to use problem+json it is not possible, it is all or nothing. Am I right?
I'm very curious what's the purpose of having jsonld in error_formats if you don't want it to be used when the request format is jsonld. When will it be used?
Well we have some front end team who want to make our life difficult ^^. It was pretty difficult to explain to them the benefit of using LD format