PUT or POST: The REST of the Story
jcalcote.wordpress.com
jcalcote.wordpress.com
Although the spec makes stronger assertions about its semantics than this, namely that the body of a PUT is supposed to a full replacement for the resource at the URL in question.
However I don't think any clients or middleware take advantage of this or would reliably be able to take any useful advantage of this.
Whereas idempotence is something which client and middleware can usefully take advantage of - eg a browser can safely re-try an idempotent request whereas it can't safely retry a general POST.
Allowing PUT to be used for requests which are idempotent but not technically full replacement updates (eg partial updates) would allow middleware to know that they're safe to repeat.
By constraining the use of PUT to 'full replacement' updates, you deny people a useful way to signal idempotence for other more general kinds of idempotent updates.
http://greenbytes.de/tech/webdav/draft-dusseault-http-patch-...
"PATCH is neither safe or idempotent as defined by [RFC2616] Section 9.1."
The only semantics it has seems to be "change this resource in some way". Sometimes such a change might be idempotent, sometimes not, and the PATCH method provides no way of communicating this.
Personally I see little advantage from adding a PATCH method. Its semantics, as far as any generalised client software or middleware are concerned, seems the safe as POST.
Really the question which this raises is: for what reasons are new REST methods justified?
I think Fielding et al are vague on this topic, and I think the vagueness shows in HTTP (and in proposed extensions like PATCH)
Personally I think new methods should only be justified where they have generalised semantics which can be exploited by middleware (or middleware-like layers in client software) and where no existing method is available to express these semantics. Terms like 'safe' and 'idempotent' are relevant and useful properties to consider at this level.
The data-level semantics (like 'applies a diff to' or 'does something approximately like a full update to') aren't really relevant when it comes to request methods, unless they are properties which it's genuinely useful for generic middleware to know about.
I say this because hypertext and standardised hypertext media types and relations are already great at helping people discover available operations, together with their data/domain-level semantics, without the need for any new request methods.
I believe that PATCH was created because people couldn't come to a consensus on whether PUT was required to replace the whole entity or whether it was allowed to have patch-like abilities.
It is hand-wavey isn't it. The whole REST concept smells of post-hoc generalisation based on just one significant example, HTTP, and as such there seems to be a lot of confused but zealous hermeneutics involved in determining the One True RESTful Way To Do HTTP both from the HTTP RFCs and Fielding's other writings (which can be rather pompous and/or opaque).
Instead, I'd like if people went back to first principles and thought hard about what actual value certain kinds of semantics have which justify (or don't justify) making them part of the protocol, as opposed to just standardising the semantics as part of some media type or other.
Idempotence, to me, seems like something which is genuinely useful and justifies itself as part of a transfer protocol, so I'd like to see HTTP take a clear and useful stance on it.
Here's the relevant paragraph from the w3.org link:
The fundamental difference between the POST and PUT requests is reflected in the different meaning of the Request-URI. The URI in a POST request identifies the resource that will handle the enclosed entity. That resource might be a data-accepting process, a gateway to some other protocol, or a separate entity that accepts annotations. In contrast, the URI in a PUT request identifies the entity enclosed with the request -- the user agent knows what URI is intended and the server MUST NOT attempt to apply the request to some other resource.
A way to distinguish form submissions (like a credit card purchase form) which must not be repeated after submission, from things like "upload a new version of this file" which you can safely allow to be retried if they time out or fail.
This is potentially useful for a bunch of different HTTP clients and client libraries, and potentially for some proxies too.
Edit: actually PUT and DELETE are useful for caches - although not because of their idempotency, but just because they communicate the fact that the resource being PUT to or DELETEd may change as a result, hence the cache key for that URL should be purged. IIRC some caching proxies do do this.
What they should do though is purge their cache for that URI when they see a successful PUT has happened.
So, for example, for newly created objects ("POST /objects/"), you should return content with header "Content-Location: http://website.com/objects/object_id ".
http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
"If a resource has been created on the origin server, the response SHOULD be 201 (Created) and contain an entity which describes the status of the request and refers to the new resource, and a Location header (see section 14.30)."
Some of those HTTP RFCs are pretty crufty - there is a cleanup project in the works apparently: http://datatracker.ietf.org/wg/httpbis/charter/
People who don't know anything about building distributed systems hop on the REST bandwagon and before you know it they've got a monstrosity that doesn't work.
I come in as a $150 an hour consultant, explain really clearly that it's ~very~ hard to get business rules and transactions working right in a REST situation, re-architect the system with POX RPC and get it working.
When I see blog entries about the "finer points of REST" I hear ka-ching, ka-ching, ka-ching!
In RPC you can do everything you have to do in a local transaction and package it as one RPC call. Fast and simple...
I would hope that the majority of us out there using REST have a sense of perspective about it though. It's about providing services as part of the open web in a loosely coupled, organic, discoverable fashion based on standardised media types. And also about implementing lightweight APIs which observe the semantics of HTTP rather than layering stuff on top of it.
This kind of stuff is a great fit for a lot of APIs which face the open web, or which are used by clients without hard, business-critical constraints on reliability and transactionality. The semantics of HTTP obviously weren't designed for that stuff, although they do contain some features which go part-way towards helping, which is perhaps what sets some people on a slippery slope.