Subject: Re: i69: Clarify "Requested Variant" [was: New "200 OK" status codes, PATCH & PROPFIND]

From: Mark Nottingham <[email-masked]>
Date: Wed, 9 Jan 2008 17:39:16 +1100

Henrik mentioned a counterproposal in passing:

> The "requested variant" is pretty clear. The variant returned had the
> request been a GET request, or in case of the ETag returned by PUT a  
> GET
> request immediately after completion of the PUT.

I've seen at least one other person agree (assumedly after appropriate  
wordsmithing). Roy, thoughts?

On 28/12/2007, at 9:49 AM, Jamie Lokier wrote:

>
> Mark Nottingham wrote:
>>> variant
>>>    The ultimate target resource of a request after indirections
>>>    caused by content negotiation (varying by request fields) and
>>>    method association (e.g., PROPFIND) have been taken into account.
>>>    Some variant resources may also be identified directly by their
>>>    own URI, which may be indicated by a Content-Location in the
>>>    response.
>
> When a variant is identified by its own URI indicated by
> Content-Location, and keeping in mind that target of a request may
> depend on request method and other things, _how_ is that
> Content-Location URI supposed to be used?
>
> Does it mean GET should be used with the Content-Location URI to fetch
> that specific variant, while other methods cannot be depended upon to
> access the specific variant (particularly if the specific variant was
> originally selected dependent on request method)?  If so, the unique
> role of GET on Content-Location URIs should be made clear.
>
> -- Jamie
>

--
Mark Nottingham     http://www.mnot.net/

---

From: "Roy T. Fielding" <[email-masked]>
Date: Wed, 9 Jan 2008 19:51:29 -0800

On Jan 8, 2008, at 10:39 PM, Mark Nottingham wrote:
>> request been a GET request, or in case of the ETag returned by PUT  
>> a GET
> I've seen at least one other person agree (assumedly after  
> appropriate wordsmithing). Roy, thoughts?

Variants are not returned.  I am happy to replace variant with the
right terminology (representation) if the WG doesn't mind.  That is
part of what I was talking about earlier when I said that 2616
often defines things in terms of server implementation when it
really should restrict itself to the visible interface.

....Roy

---

From: Mark Nottingham <[email-masked]>
Date: Thu, 31 Jan 2008 09:55:39 +1100

Roy, when you said you'd be happy to replace it with 'representation'  
do you mean
1) s/variant/representation/
or
2) s/requested variant/representation/
?

I think you mean #1, just want to make sure.

My 0.02;

It strikes me that if this term survives, or mutates into a new one,  
the definition should be tied directly to the concepts of selecting  
headers and the Vary header's payload. Tying it to conneg isn't good  
enough -- there are multiple types of conneg. If we buy that, the  
concept becomes more obviously tied to GET, and the issue of request  
bodies / other methods falls away. I also think that we should limit  
the use of such a term to places where we're talking about a response  
(see below).

(BTW, I note with interest that 14.44 doesn't classify Vary as a  
particular type of header, as all (AFAICT) other headers are.)

WRT a name -- how about 'selected representation'? This emphasises  
that it's the origin server doing the selection, not the client.

I also think (again, personally) that this general problem area would  
greatly benefit by having a crisper definition of and terminology  
around the status of POST, PUT, DELETE and other non-GET responses WRT  
whether they carry a representation or not.

I've pasted below all instances of 'variant' from 2616 outside of the  
term's definition, with some (again, personal) comments. I'm starting  
to suspect we have a number of inter-related issues here...

10.2.2 (201 Created):
> A 201 response MAY contain an ETag response header field indicating  
> the current value of the entity tag for the requested variant just  
> created, see section 14.19.
I find this just plain weird. On POST responses, it implies that you  
can negotiate for response headers on another resource and get them  
tunnelled back in the current response. If there's a Vary header  
present, does it apply to that resource too? If not, how do you know  
what the requested variant really was?

On PUT responses, it's a little more sane, but the language forces the  
requested variant to be the same as that just created; i.e., if  
there's a chance of conneg, the Accept-* headers have to be set in  
lockstep with what you're PUTting. So, you'd better not set Accept- 
Encoding: gzip unless the request entity is also content-coded with  
gzip, and AFAIK many implementations will have problems here, because  
these mechanisms tend to be taken out of developers' hands.

10.2.5 (204 No Content):
> The server has fulfilled the request but does not need to return an  
> entity-body, and might want to return updated metainformation. The  
> response MAY include new or updated metainformation in the form of  
> entity-headers, which if present SHOULD be associated with the  
> requested variant.

This makes internal sense; see comments about adjusting the definition  
above.

10.2.7 (206 Partial Content) and 10.3.5 (304 Not Modified):
> The response MUST include the following header fields:
[...]
> - Expires, Cache-Control, and/or Vary, if the field-value might  
> differ from that sent in any previous response for the same variant

Here's where IMO a distinct term does add some value; if we said  
'representation', it would be tied to a particular entity, which  
doesn't make much sense. OTOH 'variant' doesn't clarify things  
greatly, as it's currently defined. "...any previous instance of the  
selected representation'?

14.14 (Content-Location)
> The Content-Location entity-header field MAY be used to supply the  
> resource location for the entity enclosed in the message when that  
> entity is accessible from a location separate from the requested  
> resource's URI. A server SHOULD provide a Content-Location for the  
> variant corresponding to the response entity; especially in the case  
> where a resource has multiple entities associated with it, and those  
> entities actually have separate locations by which they might be  
> individually accessed, the server SHOULD provide a Content-Location  
> for the particular variant which is returned.

This is where things get fairly muddy. Variant is currently defined as  
a kind of representation, but here all of the sudden it's treated as a  
resource and given a URI. The first instance could probably be  
replaced by just 'resource', or just drop 'for the variant' entirely;  
in the second, 'representation' would probably suffice.

14.19 (ETag)
> The ETag response-header field provides the current value of the  
> entity tag for the requested variant.

Makes sense here, but 'requested/selected representation' would do  
just fine.

14.25 (If-Modified-Since)
> The If-Modified-Since request-header field is used with a method to  
> make it conditional: if the requested variant has not been modified  
> since the time specified in this field, an entity will not be  
> returned from the server [...]
> A GET method with an If-Modified-Since header and no Range header  
> requests that the identified entity be transferred only if it has  
> been modified since the date given by the If-Modified-Since header.  
> The algorithm for determining this includes the following cases: a)  
> If the request would normally result in anything other than a 200  
> (OK) status, or if the passed If-Modified-Since date is invalid, the  
> response is exactly the same as for a normal GET. A date which is  
> later than the server's current time is invalid. b) If the variant  
> has been modified since the If-Modified-Since date, the response is  
> exactly the same as for a normal GET. c) If the variant has not been  
> modified since a valid If- Modified-Since date, the server SHOULD  
> return a 304 (Not Modified) response.

14.28 (If-Unmodified-Since)
> If the requested variant has been modified since the specified time,  
> the server MUST NOT perform the requested operation, and MUST return  
> a 412 (Precondition Failed).

14.29 (Last-Modified)
> The Last-Modified entity-header field indicates the date and time at  
> which the origin server believes the variant was last modified.
Interestingly, Last-Modified validation is defined in terms of  
'requested variant', whereas ETag validation (If-Match, If-None-Match)  
seem to go out of their way to say that *any* entity that meets the  
conditional can be returned, and never mind the selecting headers. I'd  
be interested in hearing if any implementations actually do that, and  
unless some are found, I'd suggest we need to tighten up how ETag  
validation is defined..

---

From: "Brian Smith" <[email-masked]>
Date: Wed, 30 Jan 2008 17:54:23 -0800

Mark Nottingham wrote:
> I find this just plain weird. On POST responses, it implies 
> that you can negotiate for response headers on another 
> resource and get them tunnelled back in the current response. 
> If there's a Vary header present, does it apply to that 
> resource too? If not, how do you know what the requested 
> variant really was?

Also, look at AtomPub (RFC 5023). When you post anything with a type
other than application/atom+xml, you end up creating TWO resources with
one request. I've always thought that "ETag" stood for "Entity Tag", and
thus applied to the response entity.

Also, what happens when you POST a multipart document with 10 parts, and
the server creates 20 different resources from it, but doesn't create a
resource to represent the 10 parts grouped together? (Also, what do you
put in the Location header in this case?)

> This is where things get fairly muddy. Variant is currently 
> defined as a kind of representation, but here all of the 
> sudden it's treated as a resource and given a URI. The first 
> instance could probably be replaced by just 'resource', or 
> just drop 'for the variant' entirely; in the second, 
> 'representation' would probably suffice.

When I POST something, I will get a response with an entity in it. The
entity will be some kind of document that describes the resource(s) I
created with the post. If the server also created a resource that
contains the same information as the response entity, then it will
include a Content-Location header. The Content-Location header means
something like "this is where you can retrieve (a variant of) the
response entity." If there is no Content-Location, then there is no
obvious way to retrieve (a variant of) the response entity if you forget
it.

- Brian

---

From: Yves Lafon <[email-masked]>
Date: Thu, 31 Jan 2008 04:48:52 -0500 (EST)

> thus applied to the response entity.

ETag is a response header and not an entity header (and yes, it is really 
confusing), so when you have a CL and an ETag for the same entity, you 
can't link the two, as it relates only to the Request-URI, even if it 
seems logical to do so.

The definition of 201 assumes that only one resource is created, so if a 
POST creates multiple new resources, 200 should be returned instead of 
201. However, in the text:
http://tools.ietf.org/html/draft-ietf-httpbis-p2-semantics-01#section-9.2.2
<<<
The response SHOULD include an entity containing a list of resource 
characteristics and location(s) from which the user or user agent can 
choose the one most appropriate.
Should we keep this "multiple locations for one resource" paradigm?

> obvious way to retrieve (a variant of) the response entity if you forget

And if you GET a resource like http://www.example.com/foo/ , edit it and 
want to do a PUT, most of the time you'll fail because chances are high 
you don't have a CL indicating you are editing 
http://www.example.com/foo/index.fi.html (or at list you intend to do 
this)

-- 
Baroula que barouleras, au tiéu toujou t'entourneras.

         ~~Yves

---

From: "Brian Smith" <[email-masked]>
Date: Thu, 31 Jan 2008 05:07:27 -0800

Yves Lafon wrote:
> > Also, look at AtomPub (RFC 5023). When you post anything 
> > with a type other than application/atom+xml, you end up
> > creating TWO resources with one request. I've always
> > thought that "ETag" stood for "Entity Tag", and thus
> > applied to the response entity.
> 
> ETag is a response header and not an entity header (and yes, 
> it is really confusing), so when you have a CL and an ETag 
> for the same entity, you can't link the two, as it relates 
> only to the Request-URI, even if it seems logical to do so.

What about part 2, section 8.4 (HEAD):
http://www.ietf.org/internet-drafts/draft-ietf-httpbis-p2-semantics-01.t
xt

"If the new field values indicate that the cached entity differs from
the current entity (as would be indicated by a change in Content-Length,
Content-MD5, ETag or Last-Modified". Content-Length, Content-MD5, and
Last-Modified are all entity headers. 

> The definition of 201 assumes that only one resource is 
> created, so if a POST creates multiple new resources, 200 
> should be returned instead of 201. 

If Content-Location = Location (as in RFC 5023), or if "201 Created"
really implies the creation of only one resource, then the meaning of
ETag is totally clear. However, Content-Location = Location will only be
the case when a resource is self-describing (contains a hyperlink to
itself).

I can see that the language that describes 9.2.2 uses singular language
("a new resource"), but if the intention is that exactly one new
resource is created, then I think it should be more explicit. If only
one resource is allowed to be created, then doesn't RFC 5023 effectively
require AtomPub servers to be non-compliant with RFC 2616? And, does
this restriction to one resource being created also imply that, when
Content-Location <> Location, the entity linked to by Content-Location
is a variant of the resource linked to in the Location (which would
again cause problems with RFC 5023 and probably others)?

> And if you GET a resource like http://www.example.com/foo/ , 
> edit it and want to do a PUT, most of the time you'll fail 
> because chances are high you don't have a CL indicating you 
> are editing http://www.example.com/foo/index.fi.html (or at 
> list you intend to do
> this)

- Brian

---

From: Julian Reschke <[email-masked]>
Date: Thu, 31 Jan 2008 15:04:19 +0100

> Should we keep this "multiple locations for one resource" paradigm?

First of all, I do not agree with the "single new resource" 
interpretation. As Brian observed, that would be a conflict with RFC5023.

> ...

BR, Julian

---

From: Yves Lafon <[email-masked]>
Date: Thu, 31 Jan 2008 10:14:00 -0500 (EST)

On Thu, 31 Jan 2008, Julian Reschke wrote:

> First of all, I do not agree with the "single new resource" interpretation. 
> As Brian observed, that would be a conflict with RFC5023.

In that case, we need to amend the current text as I read it as implying 
there is only one new resource.
Also:
<<<
    A 201 response MAY contain an ETag response header field indicating
    the current value of the entity tag for the requested variant just
    created, see Section 6.1 of [Part4].
Should be:
<<<
    If one single resource is created, a 201 response MAY contain...

         ~~Yves