Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Being able to determine if only json or xml should be handled, instead of both. #49

Open
2 tasks done
acelaya opened this issue Nov 23, 2019 · 1 comment
Open
2 tasks done

Comments

@acelaya
Copy link
Contributor

acelaya commented Nov 23, 2019

I have run into this use case:

My application has a JSON API which is served under the /rest path, but also 3 or 4 more routes which are not part of this API context.

For the API I use "problem details" for the errors, but I also have some other error handling logic for the other routes.

Because of this, my middleware pipeline looks more or less like this:

// ...

$app->pipe(Zend\Stratigility\Middleware\ErrorHandler::class);
$app->pipe('/rest', Zend\ProblemDetails\ProblemDetailsMiddleware::class);

// More middlewares...

$app->pipe('/rest', Zend\ProblemDetails\ProblemDetailsNotFoundHandler::class);
$app->pipe(App\NotFoundHandler::class);

With this approach, most of the use cases work as expected, except when a request is performed to a not-found path which starts with /rest, proividing a non-JSON Accept header, but one that matches *+xml.

This usually happens when a request is performed from a browser, in which case the Accept has the value text/html,application/xhtml+xml,application/xml...

This is making the ProblemDetailsNotFoundHandler to generate an xml response, but I would expect/like it to be skipped and my custom NotFoundHandler (the second one) to be executed instead.

Proposal

In order to "solve" this, the first thing that comes to my mind is this approach:

Allowing to dynamically determine which "contexts" should be enabled for the module, as in "JSON only", "XML only" or "both".

I see that currently, the headers that determine if the ProblemDetailsMiddleware and the ProblemDetailsNotFoundHandler should act as error handlers, are hardcoded on ProblemDetailsResponseFactory::NEGOTIATION_PRIORITIES.

Since the three classes make use of that constant to call a Negotiator instance, maybe the whole logic could be wrapped into a helper which is injected in the three of them.

This helper could then get the "context" configuration or fallback to "both", keeping current behavior.

Let me know if you think this makes sense, or if you think there's any simpler way to achieve the same result.

In any case, I'm open to contribute a PR with the required changes.

@weierophinney
Copy link
Member

This repository has been closed and moved to mezzio/mezzio-problem-details; a new issue has been opened at mezzio/mezzio-problem-details#2.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants