Wavering on PUT

Joe Gregorio

I am now wavering in my support for the HTTP verb PUT. I used to think that it had wide applicability but now I am beginning to question that. Clemens Vasters talks a little about the applicability of using PUT to create a new resource. From the experimenting with RESTLog I know that creating a resource is better done by a POST and then returning the URL of the created resource in the Location: header. You avoid, or can more easily control concurrency problems when the URL creation is specified by the server. ( Now that I think of it, what's wrong with a belt and suspenders strategy and also delivering that new URL in a SOAP envelope...)

Any way, Clemens goes on to point out problems with updating a resource with PUT. Now Sam Ruby thinks this is just a SMOP. It actually may be, if you use ETags to guard against concurrent updates. Even if this were a solvable problem, there is a deeper problem from the semantics of PUT. You see, PUT is supposed to be an exact copy of what you get if you do a GET, modulo someone else updating things between your calls. Now I originally thought this was a good way to do updates to stories in RESTLog, but as my work progresses I realize it may not be the best way to go. For example, what if I want to add a field to the 'item' to track the last time it was updated? The best place to track and update that information would be on the server. So now I end up taking in an updated 'item' via PUT but now RESTLog would have to modify it to update the 'lastUpdated' element. I won't be returning the same exact XML as was just PUT to the server. This kind of updating of the content is exactly the difference between PUT and POST. After my run-in with XForms and DELETE I am beginning to think the only two verbs I can count on are GET and POST. Just two verbs. Hopefully I won't lose any more. You can't go to zero verbs, can you?

Just testing comments.

Posted by anonymous on 2003-03-10

PUT is the only method that provides an expectation to the client of the (changed) state of the targetted resource after invocation. If that's what you want, use it. If not, use POST. That's a slight oversimplification, but not by much. Ask on rest-discuss if you want to dig further. FWIW, I don't think Clemens' examples were very indicative of common use, because he seemed to assume that the client owned part of the server's namespace (i.e. chose the URI). There are cases where that's useful, but like I said, it's probably not indicative of your situation.

Posted by Mark Baker on 2003-03-10

Mark, Thanks for the comment, as it confirms that I was using PUT correctly. What I was trying to point out was that over time my interface is evolving and I am slipping from one where PUT would be appropriate to one where POST is more appropriate. I am wondering if this was just a fluke or will this become a pattern and I am better off avoiding PUT.

Posted by Joe on 2003-03-11

Joe, FWIW, I think using PUT for resource create is generally a bad idea. Most of the time, it makes sense to have the client POST to some sort of collection resource. This can be thought of as 'appending to the document' eg, POST /news' appends to the document containing the list of news stories and results in the creation of the URL /news/0232. This is, I believe, how POST was largely intended. This is different from PUT which was meant to be merely for updates. - Bo

Posted by Bo on 2003-03-11

I've been trying to implement ETags for concurrent updates via REST to index profiles for my company's search engine (I'll be posting something to my blog soon). Unfortunately I'm either missing something or you can't handle If-Match headers from CGIs. Duncan

Posted by Duncan Wilcox on 2003-03-11

Duncan, I remember running into the same thing with security headers. I wanted to see if I could get the Basic Authentication information and do the authentication myself. Either it was impossible or was controlled by a setting I couldn't get to from .htaccess.

Posted by Joe on 2003-03-11

I'd still like to see some actual proof that PUT demands octet-by-octet storage of the enclosed entity. RFC2616 certainly doesn't say this anywhere. It seems to be folkloric. Tamino's HTTP interface for example does not provide this behavior. PUTing will return on GET. So it preserves the infoset, not each byte. I get the sense that entity preservation is context-specific; if you're storing source code it should preserve each btye, but if you're storing date serialized as XML, only the infoset need be preserved. Even if you want to augment the PUT entity with your own data there's no reason why you can't filter it out when a GET is performed. This is an implemenation not a protocol issue.

Posted by Jeffrey Winter on 2003-03-12

comments powered by Disqus