Sunday, February 2, 2014

According to the HTTP/1.1 Spec:
The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line
In other words, POST is used to create.
The PUT method requests that the enclosed entity be stored under the supplied Request-URI. If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server. If the Request-URI does not point to an existing resource, and that URI is capable of being defined as a new resource by the requesting user agent, the origin server can create the resource with that URI."
That is, PUT is used to create or update.
So, which one should be used to create a resource? Or one needs to support both?
share|improve this question
10 
It may be helpful to use the definitions in HTTPbis - Roy put a fair amount of work into clarifying them. See:tools.ietf.org/html/… –  Mark Nottingham Oct 23 '11 at 21:03 
4 
Just to bring @MarkNottingham's comment to the latest revision, here's POST and PUT, as defined on HTTPbis. –  Marius Butuc Nov 18 '12 at 1:58 
8 
It seems to me that this debate has arisen from the common practice of oversimplifying REST by describing the HTTP Methods in terms of CRUD operations. –  Stuporman Feb 14 '13 at 17:05
1 
Unfortunally the first answers are wrong about POST. Check my answer for a better explanation of the differences: stackoverflow.com/a/18243587/2458234 –  7hi4g0 Nov 25 '13 at 5:21
 
PUT and POST are both unsafe methods. However, PUT is idempotent, while POST is not. - See more at:restcookbook.com/HTTP%20Methods/put-vs-post/… –  Dinesh Saini Jan 10 at 20:26
add comment

22 Answers

up vote1106down voteaccepted
Overall:
Both PUT and POST can be used for creating.
You have to ask "what are you performing the action to?" to distinguish what you should be using. If you want to use POST then you would do that to a list of questions. If you want to use PUT then you would do that to a particular question.
Great both can be used, so which one should I use in my RESTful design:
You do not need to support both PUT and POST.
Which is used is left up to you. But just remember to use the right one depending on what object you are referencing in the request.
Some considerations:
  • Do you name your URL objects you create explicitly, or let the server decide? If you name them then use PUT. If you let the server decide then use POST.
  • PUT is idempotent, so if you PUT an object twice, it has no effect. This is a nice property, so I would use PUT when possible.
  • You can update or create a resource with PUT with the same object URL
  • With POST you can have 2 requests coming in at the same time making modifications to a URL, and they may update different parts of the object.
An example:
POST:
Used to modify and update a resource
POST /questions/ HTTP/1.1
Host: wahteverblahblah.com
Note that the following is an error:
POST /questions/ HTTP/1.1
Host: wahteverblahblah.com
If the URL is not yet created, you should not be using POST to create it while specifying the name. This should result in a 'resource not found' error because  does not exist yet. You should PUT the  resource on the server first.
You could though do something like this to create a resources using POST:
POST /questions HTTP/1.1
Host: wahteverblahblah.com
Note that in this case the resource name is not specified, the new objects URL path would be returned to you.
PUT:
Used to create a resource, or overwrite it. While you specify the resources new URL.
For a new resource:
PUT /questions/ HTTP/1.1
Host: wahteverblahblah.com
To overwrite an existing resource:
PUT /questions/ HTTP/1.1
Host: wahteverblahblah.com
share|improve this answer
394 
I think one cannot stress enough the fact that PUT is idempotent: if the network is botched and the client is not sure whether his request made it through, it can just send it a second (or 100th) time, and it is guaranteed by the HTTP spec that this has exactly the same effect as sending once. –  Jörg W MittagMar 10 '09 at 15:17
3 
@Jörg W Mittag: Thanks for the emphasis, I agree. –  Brian R. Bondy Mar 10 '09 at 15:19
15 
@Jörg W Mittag: Not necessary. The second time could return 409 Conflict or something if the request has been modified in meantime (by some other user or the first request itself, which got through). –  MitarNov 27 '11 at 23:28
9 
@Mitar: Yes, you are right. What would a good "catch phrase" be for idempotency in HTTP? Perhaps: "The client is not responsible for anything bad that happens if it sends the request multiple times." – Jörg W Mittag Nov 28 '11 at 2:04 
159 
If I'm not mistaken, what we should be stressing is that PUT is defined to be idempotent. You still have to write your server in such a way that PUT behaves correctly, yes? Perhaps it's better to say "PUT causes the transport to assume idempotence, which may affect behavior of the transport, e.g. caching." – Ian Ni-Lewis Dec 28 '11 at 2:05 
show 8 more comments
You can find assertions on the web that say
Neither is quite right.

Better is to choose between PUT and POST based on idempotence of the action.
PUT implies putting a resource - completely replacing whatever is available at the given URL with a different thing. By definition, a PUT is idempotent. Do it as many times as you like, and the result is the same. x=5 is idempotent. You can PUT a resource whether it previously exists, or not (eg, to Create, or to Update)!
POST updates a resource, adds a subsidiary resource, or causes a change. A POST is not idempotent, in the way that x++ is not idempotent.

By this argument, PUT is for creating when you know the URL of the thing you will create. POST can be used to create when you know the URL of the "factory" or manager for the category of things you want to create.
so:
POST /expense-report
or:
PUT  /expense-report/10929
share|improve this answer
17 
I agree, wherever idempotence is concerned it should trump any other concerns since getting that wrong can cause many many unexpected bugs. –  Josh Oct 26 '10 at 5:56
3 
If POST can update a resource, how is that not idempotent? If I change a students age using PUT and do that 10x times the students age is the same if I did it once. –  Schneider May 6 '11 at 10:54
8 
@Schneider, in this case your server is making an extra effort to guarantee idempotence, but it is not advertising it. Browsers will still warn the user if they try to reload such a POST request. –  Tobu Jan 6 '12 at 10:53
13 
@Schneider POST may create a subsidiary resource; hence you can POST to collection, like POST /expense-reports and it would create as many entities (expense reports) on your server as the quantity of requests you've sent, even if they are completely similar. Think of it as inserting the same row in the DB table (/expense-reports) with auto-incremented primary key. Data remains the same, key (URI in this case) is generated by server and is different for every other insert (request). So, POST effect can be idempotent, but also may not. Hence, POST is not idempotent. –  Snifff Jan 26 '12 at 17:32 
4 
Let's say we have entities which may have two properties - name and date. If we have an entity with an existing name and date, but then make requests to it specifying only a name, the proper behavior ofPUT would be to obliterate the date of the entity, whereas POST may update only the properties specified, leaving the unspecified properties as they were before the request was made. Does that sound correct/reasonable, or is it an improper use of PUT (I saw references to PATCH, which it seems would be more appropriate, but doesn't exist yet)? –  Jon z May 8 '13 at 18:28 
show 4 more comments
  • POST to a URL creates a child resource at a server defined URL.
  • PUT to a URL creates/replaces the resource in it's entirety at the client defined URL.
  • PATCH to a URL updates part of the resource at that client defined URL.
The relevant specification for PUT and POST is RFC 2616 §9.5ff.
POST creates a child resource, so POST to /items creates a resources that lives under the/items resource. Eg. /items/1
PUT is for creating or replacing something with a URL known by the client. It's also idempotent as it replaces the resource in it's entirety.
Therefore PUT is only a candidate for CREATE where the client already knows the url before the resource is created. Eg. /blogs/nigel/entry/when_to_use_post_vs_put as the title is used as the resource key
The RFC reads like this:
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. If the server desires that the request be applied to a different URI,
Note: PUT has mostly been used to update resources (by replacing it in it's entirety), but recently there is movement towards using PATCH for updating existing resources, as PUT specifies that it replaces the whole resource. RFC 5789.
share|improve this answer
10 
Or from the other side of the fence: PUT if the client determines the resulting resource's address, POST if the server does it. –  DanMan Nov 28 '12 at 19:47
1 
I think that this answer should be edited to make it more clear what @DanMan pointed in a very simple way. What I find the most valuable here is the note at the end, stating that a PUT should be used only for replacing the whole resource. –  Hermes Nov 26 '13 at 22:37
 
Thanks. I'll make that clearer. Good feedback! –  Nigel Thorne Nov 28 '13 at 5:40 
add comment
I'd like to add my "pragmatic" advice. Use PUT when you know the "id" by which the object you are saving can be retrieved. Using PUT won't work too well if you need, say, a database generated id to be returned for you to do future lookups or updates.
So: To save an existing user, or one where the client generates the id and it's been verified that the id is unique:
PUT /user/12345 HTTP/1.1  <-- 12345="" code="" create="" get="" host:="" http="" id="" mydomain.com="" providing="" return="" that="" the="" user="">
Otherwise, use POST to initially create the object, and PUT to update the object:
POST /user HTTP/1.1   <--- 12345="" code="" create="" host:="" http="" mydomain.com="" put="" returns="" server="" the="" update="" user="">
share|improve this answer
add comment
POST means "create new" as in "Here is the input for creating a user, create it for me".
PUT means "insert, replace if already exists" as in "Here is the data for user 5".
You POST to example.com/users since you don't know the URL of the user yet, you want the server to create it.
You PUT to example.com/users/id since you want to replace/create a specific user.
POSTing twice with the same data means create two identical users. PUTing twice with the same data creates the user the first and updates him to the same state the second time (no changes). Since you end up with the same state after a PUT no matter how many times you perform it, it is said to be "equally potent" every time - idempotent. This is useful for automatically retrying requests. No more 'are you sure you want to resend' when you push the back button on the browser.
A general advice is to use POST when you need the server to be in control of URL generation of your resources. Use PUT otherwise. Prefer PUT over POST.
share|improve this answer
5 
Good answer - especially the last paragraph. –  Brian Kelly Oct 24 '11 at 0:59
add comment
Use POST to create, and PUT to update. That's how Rails is doing it, anyway.
PUT    /items/1      #=> update
POST   /items        #=> create
share|improve this answer
2 
Good insight on rails. –  User1 Dec 15 '09 at 23:47
 
POST /items adds a new item to an already defined resource ('item'). It does not, as the answer says, "create a group." I don't understand why this has 12 votes. –  David James Jun 21 '12 at 5:26 
 
Out of the box, Rails does not support 'creating a group' via REST. To 'create a group' by which I mean 'create a resource' you have to do it via the source code. –  David James Jun 21 '12 at 5:28
 
It has 12 votes because it predates the change that was made that added the group thing. I've reverted the change. –  Tim Sullivan Jun 21 '12 at 15:20
3 
This is a fair guideline, but an oversimplification. As the other answers mention, either method could be used for both create and update. –  Brad Koch Mar 7 '13 at 15:55
add comment
I like this advice, from RFC 2616's definition of PUT:
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.
This jibes with the other advice here, that PUT is best applied to resources that already have a name, and POST is good for creating a new object under an existing resource (and letting the server name it).
I interpret this, and the idempotency requirements on PUT, to mean that:
  • POST is good for creating new objects under a collection (and create does not need to be idempotent)
  • PUT is good for updating existing objects (and update needs to be idempotent)
  • POST can also be used for non-idempotent updates to existing objects (especially, changing part of an object without specifying the whole thing -- if you think about it, creating a new member of a collection is actually a special case of this kind of update, from the collection's perspective)
  • PUT can also be used for create if and only if you allow the client to name the resource. But since REST clients aren't supposed to make assumptions about URL structure, this is less in the intended spirit of things.
share|improve this answer
3 
Your last comment about PUT makes a good point. –  hotshot309 Apr 4 '12 at 18:01
2 
"POST can also be used for non-idempotent updates to existing objects (especially, changing part of an object without specifying the whole thing" That's what PATCH is for –  Snuggs May 4 '12 at 22:11 
add comment
REST is a very high-level concept. In fact, it doesn't even mention HTTP at all!
If you have any doubts about how to implement REST in HTTP, you can always take a look at the Atom Publication Protocol (AtomPub) specification. AtomPub is a standard for writing RESTful webservices with HTTP that was developed by many HTTP and REST luminaries, with some input from Roy Fielding, the inventor of REST and (co-)inventor of HTTP himself.
In fact, you might even be able to use AtomPub directly. While it came out of the blogging community, it is in no way restricted to blogging: it is a generic protocol for RESTfully interacting with arbitrary (nested) collections of arbitrary resources via HTTP. If you can represent your application as a nested collection of resources, then you can just use AtomPub and not worry about whether to use PUT or POST, what HTTP Status Codes to return and all those details.
To add members to a Collection, clients send POST requests to the URI of the Collection.
share|improve this answer
5 
There's nothing wrong with allowing PUT to create resources. Just be aware that it means that the client provides the URL. –  Julian Reschke Apr 7 '10 at 7:47
 
There's something very wrong with allowing PUT to create resources: the client provides the URL. That's the server's job! –  Joshcodes Oct 29 '13 at 17:33
add comment
New answer (now that I understand REST better):
PUT is merely a statement of what content the service should, from now on, use to render representations of the resource identified by the client; POST is a statement of what content the service should, from now on, contain (possibly duplicated) but it's up to the server how to identify that content.
PUT x (if x identifies a resource): "Replace the content of the resource identified by x with my content."
PUT x (if x does not identify a resource): "Create a new resource containing my content and use xto identify it."
POST x: "Store my content and give me an identifier that I can use to identify a resource (old or new) containing said content (possibly mixed with other content). Said resource should be identical or subordinate to that which x identifies." "y's resource is subordinate to x's resource" is typically but not necessarily implemented by making y a subpath of x (e.g. x = /foo and y = /foo/bar) and modifying the representation(s) of x's resource to reflect the existence of a new resource, e.g. with a hyperlink toy's resource and some metadata. Only the latter is really essential to good design, as URLs are opaque in REST -- you're supposed to use hypermedia instead of client-side URL construction to traverse the service anyways.
In REST, there's no such thing as a resource containing "content". I refer as "content" to data that the service uses to render representations consistently. It typically consists of some related rows in a database or a file (e.g. an image file). It's up to the service to convert the user's content into something the service can use, e.g. converting a JSON payload into SQL statements.
Original answer (might be easier to read):
PUT /something (if /something already exists): "Take whatever you have at /something and replace it with what I give you."
PUT /something (if /something does not already exist): "Take what I give you and put it at/something."
POST /something: "Take what I give you and put it anywhere you want under /something as long as you give me its URL when you're done."
share|improve this answer
add comment