According to book, PUT should set all the resource state, including any links, but ...

42 views
Skip to first unread message

albrikt a

unread,
Jun 15, 2014, 4:14:54 PM6/15/14
to restinp...@googlegroups.com

hi

Pg. 114:

"With PUT, the state encapsulated by the incoming representation will wholly replace the state of the resource hosted by the service. This obliges client to PUT all the resource state, including any links,as part of the representation it sends"

a) With some resources, not all state can be set by client, but instead some state can only be set by a service ( to my understanding, state that can only be set by a service can still be included in a resource representation sent to the client ).

But is the above quote suggesting that with PUT, client needs to send/set all resource state, even the state that should only be set by a service?!


b) If quote is indeed suggesting that clients should PUT all the resource state ( including any links ), then why doesn't example in your book have clients also set the link state when paying for order via PUT? 

Namely, as seen in example 5-8, payment resource also includes two links as part of its state and according to the above quote, clients paying for order via PUT should also set the state of those two links ( though one could argue that at the time client initiated payment via PUT, the state of resource didn't yet include those two links as part of its state <-- but that's a bit confusing, since that's like saying an instance of a class has a property at certain points of execution, but it doesn't have that property at other points of execution)!

thank you

Jørn Wildt

unread,
Jun 15, 2014, 5:19:32 PM6/15/14
to restinp...@googlegroups.com
The semantics of PUT is "complete replacement" and thus you will have to include links and all the other stuff when doing a replace. It feels somewhat silly - and it is - but its a historical fact that the designers of HTTP don't want to change (which makes sense). Try googling for "http partial PUT" and see what you get (but don't mention the war :-).

Here is the best citation I have been able to find last time I was looking:

Fielding:
> In the web-as-deployed, partial updates often use the PUT method.

In the Web as defined, standardized, and deployed, those partial
updates using the PUT method are not interoperable with standard
HTTP/1.x servers.  That has been known since the idea was first
brought up and has not changed since then.  We could not make
non-compatible changes to an existing method in 1996, nor 1999,
nor can we do so now in 2012.  There is no such thing as partial
updates using PUT.



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

albrikt a

unread,
Jun 15, 2014, 5:45:17 PM6/15/14
to restinp...@googlegroups.com
hi

"Try googling for "http partial PUT" and see what you get"


I'm familiar with the whole PUT shenanigans, but I didn't think full resource state also includes links and state that should only be set by a service. 

Anyways:

a) "The semantics of PUT is "complete replacement" and thus you will have to include links and all the other stuff when doing a replace"

Just to be sure ... so if resource has a state that should only be set by a service, then we can't use PUT?! 

b) why then doesn't example in book have clients also set the two link states when paying for order via PUT ( since payment resource includes two links  <-- see b) in original question for details )?

thank you for your help

Jørn Wildt

unread,
Jun 15, 2014, 5:50:51 PM6/15/14
to restinp...@googlegroups.com
> Just to be sure ... so if resource has a state that should only be set by a service, then we can't use PUT?!

Sure, you can, but the server is free to do what ever it will with the payload - for instance ignoring all the links etc. that you have to send, but really don't want to do, since its just unnecessary overhead.

My point of view is that PUT was designed for document oriented access - you GET a document (at that time, mostly an HTML page or an image) - and then you replace it completely with another document. It wasn't designed for interaction with dynamic content, so the HTTP PUT semantics seems somewhat archaic with todays HTTP APIs.

/Jørn

albrikt a

unread,
Jun 15, 2014, 6:09:44 PM6/15/14
to restinp...@googlegroups.com
"Sure, you can, but the server is free to do what ever it will with the payload - for instance ignoring all the links etc. that you have to send, but really don't want to do, since its just unnecessary overhead."

But if server ignores certain state PUT by client, won't this mislead and potentially cause havoc in client app which sent that PUT request? 

"My point of view is that PUT was designed for document oriented access - you GET a document (at that time, mostly an HTML page or an image) - and then you replace it completely with another document. It wasn't designed for interaction with dynamic content, so the HTTP PUT semantics seems somewhat archaic with todays HTTP APIs."

So you do agree that example in book is violating PUT recommendations?

thank you

Jørn Wildt

unread,
Jun 16, 2014, 2:36:34 AM6/16/14
to restinp...@googlegroups.com
> But if server ignores certain state PUT by client, won't this mislead and potentially cause havoc in client app which sent that PUT request?

Well, that depends on all sorts of things, so I wouldn't say so.


>  So you do agree that example in book is violating PUT recommendations?

I haven't seen the examples in a while and I'll leave that to the author to answer.

/Jørn

Ian Robinson

unread,
Jun 16, 2014, 3:07:09 AM6/16/14
to restinp...@googlegroups.com
My opinion, which is not necessarily shared by the other authors of RiP is: PUT is not symmetric with GET. The client must PUT _everything_ that a client is responsible for, but it need not PUT things that a server does to enrich a representation. Importantly, this is not a partial PUT, it's a full PUT. (A partial PUT would be one where the client only PUTs back a portion of what it is responsible for.) When PUTting back a representation that has previously been enriched and then served up by the server, the client should probably just roundtrip any server additions, whilst treating them as opaque elements. This kind of asymmetry is there in AtomPub.

ian

Finn Neuik

unread,
Jun 16, 2014, 5:33:45 AM6/16/14
to restinp...@googlegroups.com
Ensuring that the PUT contains everything that the client is responsible for is what I've been doing too and it works well.

I think what's required is that the media type clearly distinguishes between what the client is responsible from what the server is responsible for. 
Message has been deleted

albrikt a

unread,
Jun 16, 2014, 6:53:00 AM6/16/14
to restinp...@googlegroups.com
"The client must PUT _everything_ that a client is responsible for, but it need not PUT things that a server does to enrich a representation."

By "things that enrich representations" I assume you also mean links. But do you consider state of a resource that should only be set by service also as something client is not responsible for ( and as such it should not PUT that state )?

albrikt a

unread,
Jun 16, 2014, 6:54:39 AM6/16/14
to restinp...@googlegroups.com
"I think what's required is that the media type clearly distinguishes between what the client is responsible from what the server is responsible for." 

So you personally, if you don't want client to PUT links and parts of resource state which should only be set by service, then you specify in media type documentation that links and certain parts of resource state are not the responsibility of client and as such client shouldn't include them in PUT?

albrikt a

unread,
Jun 17, 2014, 11:42:59 AM6/17/14
to restinp...@googlegroups.com
thank you all for helping me out

Jørn Wildt

unread,
Jun 18, 2014, 8:23:09 AM6/18/14
to restinp...@googlegroups.com


--

Josh Graham

unread,
Jun 18, 2014, 8:47:23 AM6/18/14
to restinp...@googlegroups.com
Totally agree, Ian.

I am also fine if the consumer is unwilling or unable to opaquely roundtrip "enriched" data in PUT, the producer will continue to enrich in subsequent GET.

Or, in other words: Postel's Maxim, bitches.


----------------------------------
From the phone

Jørn Wildt

unread,
Jun 19, 2014, 2:51:55 AM6/19/14
to restinp...@googlegroups.com
If we accept that clients don't have to round trip enriched data, what happens then if the server evolves and enrich the representation with more important data? Consider this example:

1) Day 1, server returns a user represented as { name: "John" }

2) Client PUTs { name: "Lars" } and thus updates the user name to "Lars".

3) Later, server returns { name: "Lars", address: "Mountain View 1" }

4) Client is not updated

5) Client PUTs { name: "Liam" } - what should the server do now that "address" is missing? In most cases it can just ignore the missing property and simply avoid changing the address property. So far everything is fine.

6) Later, server returns { name: "Liam", address: "Mountain View 1", token: "xyz" }. The "token" value is important for various reasons and MUST be sent back.

7) Unfortunately the client is still not upgraded, and do not send the token back. This time the server has to reject the PUT request.

The problem is that, as the server evolves, older clients won't be able to know what parts of that data it MUST send back and which parts of the data it can ignore. So by building clients that do not send everything back we break (some of) the server's ability to evolve freely and independently of the clients life cycles.

/Jørn

albrikt a

unread,
Jun 23, 2014, 10:58:41 AM6/23/14
to restinp...@googlegroups.com
Hi

I apologize for late reply, but I wasn't home for the last few days. 

Anyways, if it's not too late, may I ask the following:

The problem is that, as the server evolves, older clients won't be able to know what parts of that data it MUST send back and which parts of the data it can ignore. So by building clients that do not send everything back we break (some of) the server's ability to evolve freely and independently of the clients life cycles.

a) Why not documenting in contract what parts of a resource need to be updated by client? If later server adds new data to this resource and if this new data must also be updated by client, it can again document that in a contract?! 

b) How does the above approach cause greater coupling between clients and server than if client PUTs all the resource state?! In either case client will have to be upgraded if server adds additional parts to a resource?!

and thank you for the link

Jørn Wildt

unread,
Jun 25, 2014, 2:36:34 AM6/25/14
to restinp...@googlegroups.com
> Why not documenting in contract what parts of a resource need to be updated by client? If later server adds new data to this resource and if this new data must also be updated by client, it can again document that in a contract?!

That is correct, but you are missing an important point here. One of the premises of REST is that we cannot control all clients and/or servers implementing a certain service. Yes, the server can document new changes, but it *cannot* expect all clients to be upgraded at the same time. So, for that reason, it makes sense to pro-actively code clients in a way that is safe with respect to servers evolving independently of clients.


> How does the above approach cause greater coupling between clients and server than if client PUTs all the resource state?! In either case client will have to be upgraded if server adds additional parts to a resource?!

As I stated above, no, clients will not always be upgraded when the server adds additional parts. If you instead code clients such that they will work *even* if the server adds new stuff to the response then you will have a much more stable system that causes less pain on everybody.

/Jørn

albrikt a

unread,
Jun 25, 2014, 8:25:39 AM6/25/14
to restinp...@googlegroups.com
>  ... Yes, the server can document new changes, but it *cannot* expect all clients to be upgraded at the same time. 
> So, for that reason, it makes sense to pro-actively code clients in a way that is safe with respect to servers evolving independently of clients.

I haven't yet started learning any Web Service technology, so how this is accomplished is still pretty abstract to me, but I assume by coding clients such that they work even if server adds new data to the resource you mean that any resource state that client doesn't need isn't processed at all by this client, but instead client simply PUTs that state into a message body and sends it back to the server unchanged?

Jørn Wildt

unread,
Jun 25, 2014, 8:31:36 AM6/25/14
to restinp...@googlegroups.com
> you mean that any resource state that client doesn't need isn't processed at all by this client, but instead client simply PUTs that state into a message body and sends it back to the server unchanged?

Yes, simply GET the resource, keep the complete resource representation (including links and unknown stuff), make local modifications to it - and PUT it back again. That would be the safe way to do it - and respect the semantics of "PUT means replace *everything*" ... but it is also less efficient than only sending the sub-set of the values the client is interested in changing.

Its a trade-off just like using hypermedia/links is: both techniques reduces coupling to the server but increases the payload sent back and forth.

/Jørn

albrikt a

unread,
Jun 25, 2014, 9:08:09 AM6/25/14
to restinp...@googlegroups.com
thank you for your help

cheers

Mitch Trainham

unread,
Apr 8, 2020, 2:43:59 PM4/8/20
to restinpractice
Your logic makes complete sense, and if we were simply GETing the state as JSON for example, and then manually editing the JSON and PUTing it back, that would work fine. But in reality, if the client is a javascript application for example, they would usually deserialize the GET response into a client javascript model object, which has fixed fields, then they would edit that model, and then serialize the model back to JSON and PUT that representation, which means the client's model would still need to be updated, otherwise the new property is lost in the deserialization. How do you accomplish keeping unknown dynamically added properties as part of the client model when editing it?
To unsubscribe from this group and stop receiving emails from it, send an email to restinp...@googlegroups.com.

Ian S Robinson

unread,
Apr 8, 2020, 3:01:25 PM4/8/20
to restinp...@googlegroups.com
Hi Mitch

How about a bag of unknown properties? It’s your responsibility as a client-side developer to support the evolvability of the model: it might be a bit more effort than the regular libraries provide, but that’s the cost of long-lived apps.

Kind regards

ian 


On 8 Apr 2020, at 19:44, Mitch Trainham <mitch.t...@gmail.com> wrote:


Message has been deleted

Mitch Trainham

unread,
Apr 8, 2020, 4:33:16 PM4/8/20
to restinpractice
Sure, but I love how easily we accept something conceptually, when in practice it simply doesn't work without some hackish workaround. When we get state from a server, we don't just manipulate the state and send it back. We inject that state into our own application, and we have to have a way to get it out of our application later into the same JSON format. When our application doesn't know about the structure of the state it's receiving, then information will get lost in translation.
To unsubscribe from this group and stop receiving emails from it, send an email to restinp...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages