Clarification of PUT semantics from RFC7231

41 views
Skip to first unread message

Dmitry Pavlov

unread,
Jun 22, 2015, 8:28:04 AM6/22/15
to api-...@googlegroups.com
Hi all.

I've read http related rfc's and realize the purpose and semantics of PUT method: create or replace resource specified by URI.

But one sentence in section 4.3.4 of RFC7231 bothers me as I'm not sure how properly interpret it and apply to real world api's building:

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

I'm confused about the mentioned response status and related representation: does it referes to PUT or GET response?

In case of it's related to PUT, then I think that this sentence states the following constraint of PUT behaviour

1.We make a PUT request that responses with 200 and body
PUT /uri


HTTP
/1.1 200 OK
.....

$
{putResponseBody}

2. Then we make GET request that responses with 200 and body
GET /uri

HTTP
/1.1 200 OK
......

$
{getResponseBody}


and the the following should be true:
${putResponseBody} == ${getResponseBody}

( of course in case of no concurrent modifucations are performed that managed to change resource representation between subsequent requests)

But this also means that it's valid to do PUT requests that holds only partial (read mutable state). Here is the example to clarify my idea:

1. We have a resource that contains a mix of immutable and mutable properties:
{
 
"id" : "123",//immutable, defined once at creation time
 
"dateCreated" : "2015-06-22T12:45:00", //immutable, defined at creation time
 
"orderList" : [
     
{"name" : "widget", "qty" : 1}
 
],
 
"deliveryDate" : "2015-06-28"
}
2. Then I can make a PUT and pass only mutable fields, that are valid to change:
PUT /orders/123
{
 
"orderList" : [
     
{"name" : "widget", "qty" : 1},
     
{"name" : "gadget", "qty" : 2}
 
],
 
"deliveryDate" : "2015-06-25"
}

if PUT returns representation with "filled immutables":
HTTP/1.1 200 OK
{
 
"id" : "123",//immutable, defined once at creation time
 
"dateCreated" : "2015-06-22T12:45:00", //immutable, defined at creation time
 
"orderList" : [
     
{"name" : "widget", "qty" : 1},
     
{"name" : "gadget", "qty" : 2}
 
],
 
"deliveryDate" : "2015-06-25"
}

thus returning to client a "complete" representation.

Of course if it's referred to GET, then the example above is not correct and then we come back to "well known" put description: if field is missing in PUT body then client intentionally missed it, even if it is immutable.

I'd appreciate any help with clarification of this spec part.

Thank you!
Dmitry





Mike Kelly

unread,
Jun 22, 2015, 9:12:26 AM6/22/15
to api-...@googlegroups.com
Yes, partial PUT can exhibit this behaviour. There are many deployed applications that use PUT in this way. Unfortunately, the people in charge of the HTTP specification refuse to acknowledge this and have added wording (via HTTPbis) which attempts to explicitly prohibit this kind of partial PUT. There isn't a good technical reason for this to be the case, which is why you are confused.

My advice is to not worry about this part of the HTTP spec and use PUT to perform whatever kind of idempotent updates your application requires.

Cheers,
M

--
You received this message because you are subscribed to the Google Groups "API Craft" group.
To unsubscribe from this group and stop receiving emails from it, send an email to api-craft+...@googlegroups.com.
Visit this group at http://groups.google.com/group/api-craft.
For more options, visit https://groups.google.com/d/optout.



--

Darrel Miller

unread,
Jun 22, 2015, 11:28:12 AM6/22/15
to api-...@googlegroups.com
Dmitry,

> I'm confused about the mentioned response status and related representation: does it referes to PUT or GET response?

It is related to the GET.

The line you quoted says "equivalent" not "exactly equal". There is
nothing that precludes a server from adding immutable information to
the representation. What the client sent, and what the server returns
from the GET are still "equivalent" representations from the
perspective of the client.

Also note that the responses to PUT requests are not cacheable so you
might want to consider always returning a 204 and forcing the client
to do a GET if they really want to see what has been stored.

Darrel

Dmitry Pavlov

unread,
Jun 23, 2015, 2:37:25 AM6/23/15
to api-...@googlegroups.com
Mike, Darrel, thank you for your comments.

Personally I do not seem any bad in omitting some immutable fields of resource if the behaviour remains idempotent, because immutable fields does not influence on that in terms of data updates. At least it can greatly simplify resources, e.g. avoid "perfect" normalization when all immutables in the one resource and mutable data in the other (or dealing with passing extra information that client just blindly copies from the resource, without ability to change it).

My only concern was only about how this breaks the rule of standards, so according to your comments not much (if any)

--
С уважением,
Дмитрий Павлов
Reply all
Reply to author
Forward
0 new messages