

PUT or POST: The REST of the Story - chwolfe
http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/

======
angelbob
Quick summary: PUT is idempotent, and should be used when you're sending the
full text or properties of an item, or otherwise doing some where doing it a
second time is harmless. POST is not, and should be used for requests like
"increment this field" or "add a new sub-item to this parent item" where doing
it twice will give a very different result than doing it once.

~~~
calcnerd256
No. <http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.6> versus
<http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.5> makes it clear
that you PUT something somewhere and that you POST something to the resource
located somewhere. That is the difference. The idempotence follows from that,
but it is not the important semantic part.

~~~
mjw
Personally I feel that idempotence should be the only important semantic
component of PUT.

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.

~~~
mjw
To summarise my point there:

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.

~~~
briansmith
That is what PATCH is for.

~~~
mjw
Again the (in this case draft) RFC begs to differ:

[http://greenbytes.de/tech/webdav/draft-dusseault-http-
patch-...](http://greenbytes.de/tech/webdav/draft-dusseault-http-
patch-11.html)

"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.

~~~
briansmith
The idempotency of the patch is determined by the content-type of the request
entity, instead of being inherent to the method. The idempotency and safety of
GET, DELETE, and PUT are shaky too, because Fielding and others say that side
effects of these methods are not required to be idempotent. Really everything
about the semantics of HTTP is very hand-wavy.

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.

~~~
mjw
Hm, yeah the wording when it comes to idempotence does seem slightly vague now
I look at it again; SHOULD, rather than MUST in the RFCs at least.

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.

------
ramen
The idempotency of PUT is supposedly useful with caching web proxies, but I
don't know of any caching web proxies that support PUT. Are there any?

~~~
borisk
Hehe, a proxy cashing PUTs can spice up your REST experience. How exactly will
the proxy know someone else haven't updated a resource between 2 requests and
it's safe not to pass the 2nd request to server?

~~~
mjw
Yep - it's not safe to assume you can cache a PUT in that way. AFAIK no caches
do this.

What they should do though is purge their cache for that URI when they see a
successful PUT has happened.

------
malkia
One reason I read HN, is to learn how to come up with good titles :)

------
piotrSikora
I can't agree with last few paragraphs. "Location" header should be used for
redirections. There is "Content-Location" header which should be used to
identify real location of the content.

So, for example, for newly created objects ("POST /objects/"), you should
return content with header "Content-Location:
<http://website.com/objects/object_id> ".

~~~
mjw
The RFC begs to differ :)

<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)."

~~~
piotrSikora
Erm... I stand corrected, you're right. I think I was confused by the
description under section 14.30
([http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14...](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30)).

~~~
mjw
No worries.

Some of those HTTP RFCs are pretty crufty - there is a cleanup project in the
works apparently: <http://datatracker.ietf.org/wg/httpbis/charter/>

------
keefe
it's worth remembering that firefox won't let you PUT an attachment from a
form, it must be POST which is a real pain for dealing with couchdb sometimes

~~~
ratsbane
Not just Firefox - all HTML 4 forms support only GET and POST (though
XMLHttpRequest supports any method.) HTML 5 forms do support PUT and DELETE
though not HEAD. (I think this is accurate. Corrections appreciated.)

------
terra_t
I ~love~ REST!

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!

~~~
borisk
You're obviously (by your rate and believes) a newcomer to enterprise
architecture ;) Distributed transactions are an anti-pattern even with WS-
Transactions. And business rules belong to the services themselves, not to the
service infrastructure.

~~~
terra_t
That's the whole problem with REST; getting transactional semantics requires
distributed transactions.

In RPC you can do everything you have to do in a local transaction and package
it as one RPC call. Fast and simple...

~~~
wanderr
If only SOAP wasn't the face of RPC to most people, you probably wouldn't get
downvoted so hard. ;) SOAP is horrible but REST is worse. JSON-RPC is elegant
and simple. I wish more people would use it.

