Problem/Motivation
As of #2019123: Use the same canonical URI paths as for HTML routes, content negotiation is used to determine the response format of REST requests. Since REST clients are served from the same URLs as browsers, this applies to every request.
However, in order to make content negotiation via Accept
request header work with external caches, an application needs to add Vary: Accept
to affected responses. Otherwise an external cache will mix them up and REST clients / browsers are served with responses in random formats. For Amazon CloudFront"only acceptable value for the Vary header is Accept-Encoding. CloudFront ignores other values" so Vary: Accept
doesn't work.
AnecdotallyCloudFlare doesn't seem to support Vary: Accept
but official answers are scarce.
The following cases should be considered when evaluating any solution as to whether they'd be supported and how cleanly.
Routes:
- rss.xml - single purpose path responding with a non-html format.
- node/1 - a single purpose path responding with html only format.
- node/1.json - multipurpose path (node/1) with an extension denoting format.
- admin/foo/example.plugin_id - An arbitrary path containing some placeholder not related to format but a point)
- rest/myendpointwithvaryingformats - Accepts only conneg. (Current behaviour in 8.x, not-critical to support and can be in contrib.
Aliases
- myalias.json - an explicitly added alias with an extension denoting format (myalias.json -> node/1.json) (supported in 7.x)
- myalias.html - an alias with an extension, pointing to a regular HTML page (node/1)
- menu.pdf - an alias with a non-HTML extension, pointing to an HTML page (node/1) (supported in 7.x)
- about.json - a request comes in to an aliased path (about -> node/1) with an extension . The alias-with-extension is implicit. (not supported in 7.x
Proposed resolution
Switch to /node/1.json
and so on. Perhaps keep Content-Negotiation as an (advanced) option.
According to @klausi in #7, "Twitter, Github, Facebook etc." have switched to this.
The Spring framework prefers extensions (and query arguments) over content negotation and calls content-negotiation "problematic to use".
Roy Fielding on a discussion between extensions and query arguments denies that either"choice has anything to do with REST". This (and his whole mail) really can't be interpreted any other way but that he sees extensions compatible with REST and that he likes extensions better than query arguments.