
PUT or POST: The REST of the Story - jherdman
http://jcalcote.wordpress.com/2008/10/16/put-or-post-the-rest-of-the-story/
======
kgtm
First of all, this piece was written in 2008.

The tl;dr is that GET/DELETE/PUT are idempotent, whereas POST is not. The
author suggests that POST should be used on "collection-like" resources, e.g.
'/Persons' to create a new Person while PUT to update/create a specific Person
(i.e. you know the identifier of the Person in the system). Multiple PUTs on
that resource, with the same payload body, will not change the state of
system.

This makes sense, and, as far as I have seen, is the "normal" way to approach
REST (for various definitions of REST). What puzzles me is that the first
referenced article ("How to Create a REST Protocol") actually doesn't advocate
the PUT=CREATE mapping. Maybe I am missing something?

Reaching the article's concluding paragraph, the author states: _"PUT must
create or update a specified resource by sending the full content of that same
resource"._ OK, but this complicates matters, since the client now needs to
know _how_ to address a particular resource i.e. have implementation/domain-
specific knowledge.

My approach is using POST to create, and PUT to update (NOT _create_ /update).
I find that it simplifies things quite a bit.

~~~
peterwwillis
So let's say there's a resource that you want to update, but you don't know if
it exists or not. Either you can GET (or HEAD or something) to see if it
exists and then PUT if it exists or POST if it doesn't exist yet. _Or_ you can
just have PUT create and/or update it whether or not it exists, skipping the
requirement of knowing whether you need to create it or not. (Or did I miss
something?)

~~~
kgtm
You are one step ahead though. How can you address a resource if you don't
know beforehand the representation of its identifier? Say, you want to create
a new Employee under /Employees. Do you just issue a 'GET /Employees/1234' and
assume '1234' is a valid identifier when you get a 404? What if the system
expects a MongoDB _id such as '47cc67093475061e3d95369d'?

A workaround, as was suggested by an other poster, is that the client
interrogates the system for a valid identifier and then proceeds. This
especially makes sense when, as noted, you are dealing with resources that
belong to no collection.

~~~
ww520
All these are good points.

However, in the case where the Id is the nature key (e.g. SSN), the Id can be
known from the user input. Creating an employee is just a matter of PUT his
full record along with his SSN as the Id.

~~~
itcmcgrath
Save yourself some hassle. Don't key on SSN.

1) Encryption (and then indexing) becomes harder.

2) SSN's can change, for many reasons. (eg:
[http://consumerist.com/2008/11/can-i-change-my-social-
securi...](http://consumerist.com/2008/11/can-i-change-my-social-security-
number.html), data entry error, etc)

------
aGHz
Aside from my HTTP/REST rant, I think there's a much better discerning factor
between POST and PUT. From the HTTP spec:

"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. [...] 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. If the server desires that the request be
applied to a different URI, it MUST send a 301 (Moved Permanently) response;
the user agent MAY then make its own decision regarding whether or not to
redirect the request."

So if you want to create the user Foo and you somehow know about the URI
example.com/users/Foo, then you can directly PUT your information to that URI.
This URI points directly to the enclosed entity, the user. If you only know
the URI of the enclosing resource (aka collection), then you MUST do a POST to
example.com/users/.

So that's the semantics of it, PUT deals directly with the resource that the
URI points to, while POST deals with a collection of subordinate resources.

However, the REST catch is that if you follow the HATEOAS principle, there's
(almost+) no way you would know about example.com/users/Foo. In the REST
world, you would (almost) never use PUT for creating, because if that resource
doesn't already exist, you would (almost) never get a URI to it by traversing
the hypertext representation of the application state.

\+ I say almost because you could have something like a GET
example.com/users?name=Foo that would return 404 with the URL where to PUT to
create this user. Not sure how HATEOAS proposes you get to a URL like
example.com/users?name=Foo though, perhaps someone more knowledgeable can
pitch in.

~~~
o1iver
I am not sure about this, but I think that if you adhere to the HATEOAS
principle you could provide URIs for non-existent resources that can then be
used to PUT.

Example a user profile may contain a URI to the user's profile picture
although that does not exist yet, which means that you could grab that URI and
then PUT a picture there.

~~~
arethuza
In a RESTful API that I'm currently working on I did wonder about how best to
create URIs for resources that you want to create via a PUT. To try to stick
to the rule that "Servers must have the freedom to control their own
namespace" (which is sensible if you are going to have multiple difference
server implementations with different technology stacks) I chose to return a
_template_ URI for the container resource and then allow the client to use
this template to create URIs. Along the lines of:

<http://foo/bar/{name}>

or

<http://foo/floop.ashx?path=/bar/{name}>

The client replacing {name} with the actual intended resource name.

Not sure if this is a good idea or not - but it seems to work!

------
unoti
It seems to me that these discussions produce far more heat than light. If one
needs to build an application, what is the benefit to sweating these details
to such an extent? I don't mean to denigrate any of the fine work that's gone
to figuring out these standards. But if the application and/or API works well,
what difference does it make whether it uses post or put? I honestly would
like to be enlightened. Is the motivation to make it so that people will know
how api's work without reading about them, because they conform to a clear
standard that everyone understands? If so, that hardly seems achievable. So
I've honestly been long perplexed why people sweat this type of thing so hard.

~~~
zalambar
My mobile client is consuming your API over a lossy and high latency network.
Some of my requests will time out. Sometimes I will drop offline after sending
a request and not be able to receive the response. Which requests can I retry
safely?

------
lucisferre
Are there any examples of REST API implementations that are actually true to
the original concepts or is everything kind of a "Web API" compromise? As a
follow up, does, and should, anyone actually care really?

Is REST really just a pipe-dream in practice?

~~~
ExpiredLink
Comments like 'you are doing it wrong', and 'you haven't understood REST' are
posted to most REST articles I have seen. Obviously nobody ever has done REST
right.

~~~
pyre
Or the people that understand REST don't write about it.

~~~
Ixiaus
I've found a painful lack of examples too. There's a lot of written material
but few concrete examples from what I've found...

------
NanoWar
Good we have PATCH[1] now ;) .

[1] <http://tools.ietf.org/html/rfc5789>

------
aGHz
The issue this piece exposes is much wider than REST and completely
independent of the validity/desirability of REST. The semantics of PUT and
POST are defined in the HTTP spec, a much lower level than the architectural
one at which REST exists. As such, everyone developing HTTP-enabled code
SHOULD (RFC 2119) obey the proper semantics to make sure we all use the same
vocabulary. I mean, c'mon guys, there's only a handful of verbs!

This is HTTP not REST. You need to understand this even if you're against
REST.

(edited to remove tl;dr. It looked much longer in my text box)

~~~
artsrc
What parts of REST can you be against if you are ok with HTTP.

If REST is the architecture that HTTP is an protocol for can you really use
HTTP properly without understanding REST?

~~~
NanoWar
You could do XML-RPC over HTTP. You could do SOAP over HTTP.

Those would be rather RESTless.

~~~
artsrc
I really don't think SOAP is very ok with HTTP. It misuses the protocol and
subverts its goals. For example, version 1 used POST for safe, idempotent
requests.

------
Erwin
I'm curious how security is typically handled in REST setups.

Wouldn't you want to have some nonce anyway on requests that modify resources
(and thus allowing idempotency even if you POST everything) ?

Or are resources typically protected purely by some non-HTTP auth process,
i.e. a custom header, or username/password/API key provided as POST data?

If sending data to a resource is protected via simple basic authentication
then you can use a auto-posting form to send it on behalf of a user, if they
previously entered this data for testing in their browser. I.e. basic cross-
site request forgery.

~~~
rendezvouscp
Iron Money’s API[1] is RESTful and protected with OAuth 1.0a; since it uses
the plaintext signature method, no nonce is used for each request.

I’m not quite sure what your security question is. Since the API and web app
use different authentication schemes and have different endpoints, there is no
risk of CSRF.

[1] <https://ironmoney.com/api/>

~~~
NanoWar
I don't see HATEOAS ("API browsing") there at all. Only in the
documentation[1] I see the resource layout one time...

[1] <https://ironmoney.com/api/resources/>

~~~
rendezvouscp
Yes, hence “RESTful.” The API is definitely not a prime example of a REST API
since it doesn’t return the URIs of resources. It does, however, generally
follow the other constraints.

------
kenjackson
Does anyone else think the naming of PUT/POST actually makes things more
confusing? I feel like if they were better named at least a little confusion
would be cleared up.

