- From: James Snell <jasnell@gmail.com>
- Date: Tue, 13 Dec 2011 11:42:20 -0800
- To: Julian Reschke <julian.reschke@gmx.de>
- Cc: Mark Nottingham <mnot@mnot.net>, "Moore, Jonathan (CIM)" <Jonathan_Moore@comcast.com>, Martin Thomson <martin.thomson@gmail.com>, Alex Rousskov <rousskov@measurement-factory.com>, HTTP Working Group <ietf-http-wg@w3.org>
On Mon, Dec 12, 2011 at 1:15 PM, Julian Reschke <julian.reschke@gmx.de> wrote: > On 2011-12-08 18:56, James Snell wrote: >> >> Ok, a new draft has been published. >> >> http://www.ietf.org/id/draft-snell-http-prefer-07.txt >> >> After discussing caching issues with Mark in detail, I've made a >> number of important changes to the draft... specifically, it is >> important to point out that Prefer was always intended to be a >> behavior-negotiation mechanism, not content-negotiation. While the >> application of a behavioral preference could potentially impact the >> construction of a response, implementations should avoid utilizing >> preferences in a way that causes a variance in the caching of a >> response. For that reason, I added a new short section detailing cache >> considerations and removed the detail preference. Basically, if you're >> using Prefer for content-negotiation, you're likely doing it wrong. > > > Not convinced. Where's the difference? If the response without "Prefer" > would have been cacheable, and the presence of the Prefer header field > changes the response I receive, how is that *not* content negotiation? > >[snip] Ok, here's another run at explaining this... let me know if it makes sense and is convincing enough ;-) As I've pointed out, the Prefer mechanism is essentially behavior-negotiation, which means, it allows the client a means of politely asking the server to act a particular way when processing a request. In the case of the return-representation, return-minimal and return-accepted preferences, it is essentially negotiating with the server about the processing model for a request. Whether the content actually returned by the server is cacheable or not is a different question that will be dependent on a number of factors including the specific response code, request method and effective cache-controls. Asking a server to return a representation a modified resource has no impact on whether that representation is cacheable. Asking the server to return a minimal response (e.g. 204 No Content) also has no impact on whether the representation is cacheable. Let's look at an example... Suppose we have an api that supports to use of the return-representation and return-minimal preferences... basically, when I modify content, I can send Prefer: return-representation or Prefer: return-minimal. Specifying either of these on a GET makes absolutely no sense given that return-representation implied in the nature of GET and return-minimal should still return the representation. If an application supports alternate representations (minimal and verbose) of a resource, then it has to be prepared to deal with cacheability independently of whether Prefer is used or not. So assume we POST a resource to a collection and want a minimal reponse... POST /collection HTTP/1.1 Host: example.org Content-Type: text/plain Prefer: return-minimal {Data} ... HTTP/1.1 201 Created Location: http://example.org/collection/1 Content-Length: 0 Ok, since this is a POST (content modification), the default assumption is that the response is not cacheable (per http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-17#section-6.5). The response would have to contain specific caching information in order to be cacheable. So here, it's not a problem. Let's look at return-representation now... POST /collection HTTP/1.1 Host: example.org Content-Type: text/plain Prefer: return-representation {Data} ... HTTP/1.1 201 Created Location: http://example.org/collection/1 Content-Type: text/plain Content-Length: 6 {Data} Ok, in this example, again, the default assumption is that the response is not cacheable. It doesn't matter that return-representation was used. The server would have to include additional freshness information in the response in order to make the request cacheable (e.g a cache-control header). PUT and PATCH would be handled the same... whether the response is cacheable or not has absolutely nothing to do with which preference was passed in. The same considerations apply to returning a 202 Accepted for asynchronous processing using the return-accepted preference... again, because of the requests used, and the nature of handling 202 responses, the cacheability of the response is completely independent of the specific preference applied. So for the various return-* (and wait) preferences currently defined in the spec, it's clear that they are not content-negotiation mechanisms. Contrast that with the detail preference that I removed. In that case, the preference specifically deals with the amount of information to include in the response. Let's assume I left that in... per the definition of the preference, it's up to the server to figure out how it applies. The original intent for the preference is to affect the amount of detail included in error responses in an api (4xx and 5xx responses), primarily for debugging purposes. Again, for modification requests (DELETE, PUT, POST, PATCH, etc) the default cacheability of the response has absolutely nothing to do with the preference specified, and anyone who is caching error responses that could potentially contain request-specific content is asking for trouble anyway. (btw, it's interesting the the http spec is completely silent on the cacheability of 4xx and 5xx responses with the exception of 410). If a specific API wishes to apply the Detail preference to non-error output, then it has to be prepared to deal with the caching consequences regardless or whether Prefer is used or not. That said, however, an API that allows non-error variability in the verboseness of the non-error output would be better off defining a querystring parameter specifying the verboseness than using Prefer. Prefer: detail works great for debugging error responses, not so much for regular api use. Regardless, use of Prefer: detail would not inherently impact the caching of the response. Convinced yet? Now, if I defined a preference like "Prefer: return-atom", that would be Just Plain Silly. Preferences should be limited to behavioral options (how to handle a request, how to handle the response, how to deal with various error conditions, etc) leaving the content options up to the request uri and various Accept-* headers, etc.
Received on Tuesday, 13 December 2011 19:42:53 UTC