Re: Prefer Draft Feedback

On Mon, Dec 12, 2011 at 1:15 PM, Julian Reschke <> wrote:
> On 2011-12-08 18:56, James Snell wrote:
>> Ok, a new draft has been published.
>> 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?

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

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

  POST /collection HTTP/1.1
  Content-Type: text/plain
  Prefer: return-minimal



  HTTP/1.1 201 Created
  Content-Length: 0

Ok, since this is a POST (content modification), the default
assumption is that the response is not cacheable (per
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
  Content-Type: text/plain
  Prefer: return-representation



  HTTP/1.1 201 Created
  Content-Type: text/plain
  Content-Length: 6


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

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