5

From Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content:

An origin server MUST NOT send a validator header field (Section 7.2), such as an ETag or Last-Modified field, in a successful response to PUT unless the request's representation data was saved without any transformation applied to the body (i.e., the resource's new representation data is identical to the representation data received in the PUT request) and the validator field value reflects the new representation. This requirement allows a user agent to know when the representation body it has in memory remains current as a result of the PUT, thus not in need of being retrieved again from the origin server, and that the new validator(s) received in the response can be used for future conditional requests in order to prevent accidental overwrites (Section 5.2).

I can't fully understand this section... Bolded sentences seem to contradict themselves, don't they?

Note that PUT is the only verb having a section concerning validator headers (see GET/POST/DELETE/PATCH).

Community
  • 1
  • 1
sp00m
  • 47,968
  • 31
  • 142
  • 252
  • 1
    I don't see a contradiction here. The main point here is that the server can only return an Etag if what was stored actually is what the client sent. If the server modified the data, the client will have to fetch the content using a subsequent GET request. – Julian Reschke Feb 15 '17 at 11:49

1 Answers1

6

The key point is that the server may, or may not, alter the representation before storing it. From the section you linked to:

A successful PUT of a given representation would suggest that a subsequent GET on that same target resource will result in an equivalent representation being sent in a 200 (OK) response. However, there is no guarantee that such a state change will be observable, since the target... might be subject to dynamic processing by the origin server.

Therefore, the standard uses the presence or absence of the validator header to indicate to the user agent whether or not the representation has been altered.

If the representation hasn't been altered, then the server can return the validator header field, and the user agent can use that to conditionally validate the representation it just sent.

If the representation has been altered, then the user agent's representation is, by definition, invalid. Therefore no validator header is returned, and the user agent will have to do an unconditional GET.

Kevin Christopher Henry
  • 46,175
  • 7
  • 116
  • 102
  • 3
    Thanks, one remaining question though: a client has a version of a resource, modifies it, PUTs it to the server, which applies additional modifications and returns the new representation to the client. In this case, request's body != response's body. Why can't the server provide the new ETag directly within the response? The client could then check if its local ETag matches the one in the response and update its cache accordingly. This would avoid clients to GET the resource again (which response will have the exact same body as the PUT response, but this time with the ETag)... – sp00m Feb 15 '17 at 12:18
  • 2
    @sp00m: I think the confusion here is that you're assuming that the server sends the representation back in the response body to the `PUT`. But that's not the case. If you control the server then you can do it, of course, but it's not part of the standard. So in general there's no way for the user agent to know the new representation without doing a new (unconditional) `GET`. – Kevin Christopher Henry Feb 15 '17 at 12:31
  • Oh, right, here is precisely what I was missing :) Thanks! – sp00m Feb 15 '17 at 12:33
  • 2
    You might want to have a look at http://greenbytes.de/tech/webdav/rfc7240.html#return – Julian Reschke Feb 15 '17 at 13:04
  • It is interesting to note that Google API design guide suggests that PUT should return the resource: https://cloud.google.com/apis/design/standard_methods – Mitar Nov 11 '20 at 20:26
  • Also, with HTTP2 the whole GET after PUT is not a problem because server could push GET to the client together with PUT response, anticipating that the client will do the GET. – Mitar Nov 11 '20 at 20:26