Created
March 23, 2018 15:29
-
-
Save KES777/c7b9a2487b98dee19a329102844a1159 to your computer and use it in GitHub Desktop.
content negotiation draft
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Mojolicious content negotiation gotchas | |
Let's begin with parts which participate in content negotiation. | |
First of all there are client requirements and server capabilities. | |
This is obvious that we should prefer client requirements over server capabilies by default. And, if server (controller's action) wants, it may force {format}. | |
So picture is next by precedence: | |
1. Controller's action format preferences | |
$c->stash->{ format }=XXX | |
2. Query format | |
/path/script?format=XXX | |
3. Path suffix format | |
/path/script.XXX | |
4. Accept headers | |
Accept: XXX | |
5. Route default format | |
->get( '/path/script', { format => XXX } ) | |
6. Application default format | |
sub startup { | |
... | |
$app->defaults( format => XXX ); | |
Query format should take precedence over path suffix because it is more | |
specefic. Also I gather links to other frameworks and wide practice. You can | |
see them at this gist: | |
https://gist.github.com/KES777/8f6a32b9cde4404414aadffa8fb2515b | |
Most important of them are: | |
1. Rube on rails behavior | |
2. IBM knowledgebase | |
3. Enchant/Zendesk API designer | |
Currently content negotiation in Mojolicious still inconsistent. Test case: | |
https://gist.github.com/KES777/c56e5043ebde250754df34a473941864 | |
In short: application/route default {format} take precedence over requested | |
{format} in Accept header or query parameter: | |
get '/route' => { format => 'xxx' }; | |
$t->get_ok('/route?format=json')->content_is( "json\n" ); | |
got: 'xxx' | |
expected: 'json' | |
The problem because of content negotiation even not started: | |
https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Renderer.pm#L96 | |
Q: When format negotiation must be started? | |
A: Format negotiation must be started when controller's action do not force {format} | |
But becuase of the default application/route {format} is merged into stash here: | |
https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Routes/Pattern.pm#L32 | |
We can not distinguish default {format} from {format} passed from action. | |
If we could distinguish them: | |
https://github.com/KES777/mojo/commit/fd9f47307d | |
We could start content negotiation: | |
https://github.com/KES777/mojo/commit/8494aef5 | |
This distinguish is very important, because | |
1. application/route default {format} belongs to server capabilies | |
2. detected {format} from path suffix belongs to client requirementsjberg | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment