Open pomakis opened 3 years ago
Here's a real-life example of the need for the "Vary: Accept" response header. The {landingPage}/api endpoint of the CubeWerx OGC API server can serve two representations: "application/json" and "text/html". If requested directly by the Google Chrome browser, the following Accept header is automatically sent:
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
and as a result the user gets an HTML page as expected. If the request is made without an Accept header, or with an Accept header that explicitly requests "application/json" as a preferred representation, the JSON OpenAPI document is returned. Our HTML representation of this resource is a simple HTML page which makes an Ajax request to fetch the JSON representation so that it can be displayed all pretty-like using SwaggerUI. So far so good. But here's where things went wrong.
The JSON representation was being requested with the following Accept header:
Accept: application/json,*/*
which (presumably due to indicating "withCredentials: true" and therefore being more careful with the cache) always correctly fetched the JSON representation. But then sometimes later on, when the user would request the HTML representation again directly via the web browser, the raw JSON OpenAPI representation would be displayed. It turns out that it was because the web browser wasn't aware that the "Accept" header would make any difference, and decided to return the JSON representation that was cached by the earlier Ajax request.
Adding "Vary: Accept" to our responses resolved this. (This is exactly the purpose of the Vary header.) To be thorough, we also added a vendor-specific "f=json" query parameter to the URL of the Ajax request, but that shouldn't be necessary.
Note that the same applies to Accept-Encoding
and Accept-Language
, too. If the resource supports multiple encodings or languages, these need to be added to the Vary header, too.
We already have nineteen recommendations and permissions in Part 1, none of which are testable. Rather than further dilute the Standard, I would like to capture this information in the Users Guide. Hyperlinks in the Standard would point users to this additional information everywhere it's appropriate.
Section 8.7 ("Resource Encodings") of "OGC API - Common - Part 1: Core" states:
This statement should probably be more specific by referring specifically to section 5.3 of IETF RFC 7231. It also might be a good idea to give an example HTTP Accept request header to make it clear that this form of content negotiation is encouraged.
In addition to this, it should also be recommended that any OGC API resource whose representation can be negotiated via the HTTP Accept header should include a "Vary: Accept" response header. This tells the client to take multiple representations into account when caching. This recommendation could be made either in section 8.7 or in section 8.4 ("Web Caching"); I'm note sure where it'd be more appropriate.