Categories
http post put rest

What is the difference between POST and PUT in HTTP?

6041

According to RFC 2616, § 9.5, POST is used to create a resource:

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.

According to RFC 2616, § 9.6, PUT is used to create or replace a resource:

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.

So which HTTP method should be used to create a resource? Or should both be supported?

17

  • 66

    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/…

    Oct 23, 2011 at 21:03


  • 19

    Just to bring @MarkNottingham’s comment to the latest revision, here’s POST and PUT, as defined on HTTPbis.

    Nov 18, 2012 at 1:58


  • 44

    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, 2013 at 17:05

  • 6

    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, 2013 at 5:21

  • 30

    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/…

    Jan 10, 2014 at 20:26

4698

Overall:

Both PUT and POST can be used for creating.

You have to ask, “what are you performing the action upon?”, to distinguish what you should be using. Let’s assume you’re designing an API for asking questions. 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 you use is 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 the 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 defined to assume idempotency, so if you PUT an object twice, it should have no additional effect. This is a nice property, so I would use PUT when possible. Just make sure that the PUT-idempotency actually is implemented correctly in the server.
  • 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:

I wrote the following as part of another answer on SO regarding this:

POST:

Used to modify and update a resource

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Note that the following is an error:

POST /questions/<new_question> HTTP/1.1
Host: www.example.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 <new_question> does not exist
yet. You should PUT the <new_question>
resource on the server first.

You could though do something like
this to create a resources using POST:

POST /questions HTTP/1.1
Host: www.example.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/<new_question> HTTP/1.1
Host: www.example.com/

To overwrite an existing resource:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

Additionally, and a bit more concisely, RFC 7231 Section 4.3.4 PUT states (emphasis added),

4.3.4. PUT

The PUT method requests that the state of the target resource be
created or replaced with the state defined by the representation
enclosed in the request message payload.

42

  • 1172

    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.

    Mar 10, 2009 at 15:17

  • 85

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

    – Mitar

    Nov 27, 2011 at 23:28

  • 696

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

    Dec 28, 2011 at 2:05


  • 172

    @JörgWMittag Idempotence catchphrase? How about “Send and send and send my friend, it makes no difference in the end.”

    Mar 3, 2014 at 17:13


  • 65

    Thinks of them as: PUT = insert or update; POST = insert. So when you make two PUT – you get the one new record, when you do two POSTs – you get two new records.

    Aug 22, 2016 at 9:34

2435

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

15

  • 81

    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, 2010 at 5:56

  • 20

    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.

    May 6, 2011 at 10:54

  • 32

    @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, 2012 at 10:53

  • 51

    @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, 2012 at 17:32


  • 13

    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 of PUT 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, 2013 at 18:28


802

  • POST to a URL creates a child resource at a server defined URL.
  • PUT to a URL creates/replaces the resource in its 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. Sending the same post packet twice will create two resources.

PUT is for creating or replacing a resource at a URL known by the client.

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

PUT replaces the resource at the known url if it already exists, so sending the same request twice has no effect. In other words, calls to PUT are idempotent.

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 them in their entireties), but recently there is movement towards using PATCH for updating existing resources, as PUT specifies that it replaces the whole resource. RFC 5789.

Update 2018: There is a case that can be made to avoid PUT. See “REST without PUT”

With “REST without PUT” technique, the idea is that consumers are
forced to post new ‘nounified’ request resources. As discussed
earlier, changing a customer’s mailing address is a POST to a new
“ChangeOfAddress” resource, not a PUT of a “Customer” resource with a
different mailing address field value.

taken from REST API Design – Resource Modeling by Prakash Subramaniam of Thoughtworks

This forces the API to avoid state transition problems with multiple clients updating a single resource, and matches more nicely with event sourcing and CQRS. When the work is done asynchronously, POSTing the transformation and waiting for it to be applied seems appropriate.

14

  • 65

    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, 2012 at 19:47

  • 3

    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, 2013 at 22:37

  • 3

    PATCH isn’t a realistic option for at least a few years, but I agree with the ideology.

    – crush

    Oct 3, 2014 at 17:33

  • 5

    I’m trying to understand, but using PUT to create something would only make sense if the client knows for sure that the resource doesn’t exist yet, right? Following the blog example, say you have created hundreds of blog posts in a couple of years, then accidentally pick the same title as you did for a post two years ago. Now you have gone and replaced that post, which wasn’t intended. So using PUT to create would require the client to track what is taken and what is not, and could lead to accidents and unintended side effects, as well as having routes that do two entirely different things?

    Jan 30, 2015 at 9:01


  • 5

    You are correct. PUTting a blog post at the same url as an existing one would cause an update to that existing post (although you could obviously check first with a GET). This indicates why it would be a bad idea to use just the title as the URL. It would however work anywhere there was a natural key in the data… which in my experience is rare. Or if you used GUIDs

    Feb 3, 2015 at 5:20