POST vs. PUT

Musicians will understand this analogy. Have you ever tried to learn a piece that goes the wrong way? That is, you’re playing along and it’s so obvious where the next notes are going to go and instead the piece goes off in a completely different direction. Half the time you find yourself playing the notes you think the piece should use rather than the notes it does use.

For me, understanding the difference between HTTP POST and PUT is very much like that. I’ve had a great deal of trouble understanding explicitly RESTful protocols like APP because they follow the actual definition of POST and PUT instead of what is to me clearly the right definition. However, I think I’m finally starting to get it.

My mistake is in thinking that anything that creates a new page is a PUT and anything that changes an existing page is a POST. In SQL terms, POST is an UPDATE and PUT is an INSERT. However, that’s not the case. In fact, the mistake is in trying to model PUT and POST in terms of INSERT and UPDATE. They really aren’t even close.

What actually happens is this. PUT puts a page at a specific URL. If there’s already a page there, it’s replaced in toto. If there’s no page there, a new one is created. This means it’s like a DELETE followed by an insert of a new record with the same primary key.

POST, however, really has no equivalent in SQL. POST sends some data to a specified URL. The server on the other end of this URL can do whatever it wants with this data. It can store it somewhere private. (HTTP 204 NO CONTENT). It can store it in the page at the URL that was POSTed to (HTTP 205 RESET CONTENT). It can store it in a new page, in which case it returns the URL of that page in the Location field of the HTTP response header (HTTP 201 CREATED). It can use it as input for several different existing and new pages. It can throw the information away. It can insert, update, or delete records in a database (or all of the above). It can start brewing coffee (HTTP 202 ACCEPTED). It can start global thermonuclear war. POST is decidely non-side-effect free and non-idempotent.

PUT is a much more limited operation that never does anything more than PUT one page at a specified URL. It is idempotent, which is a fancy way of saying that doing it twice is the same as doing it once. Both PUT and POST can be used to create new pages. However PUT should be used when the client specifies the location for the page. PUT is normally the right protocol for a web editor like DreamWeaver or BBEdit. POST is used when the client gives sends the page to the the server, and the server then tells the client where it put it. POST is normally the right protocol for a blog editor like TypePad or anything that inputs into a content management system. In SQL analogy, POST is an INSERT with an automatically generated primary key, and PUT is an INSERT that specifies the primary key in the INSERT statement.

29 Responses to “POST vs. PUT”

  1. John Cowan Says:

    Correct on all counts. There is a view that unrestricted PUT is a Bad Thing because servers should keep control of their own URI spaces, so some servers may allow PUTs to existing URLs and not to novel ones (403 Forbidden). That gives the impression that PUT is like UPDATE, even though conceptually it’s not.

  2. Matt Says:

    More and more we’re seeing POST(a) and POST(p) being used on the rest-discuss list. The source seems to be one of Fielding’s posts from last year: http://groups.yahoo.com/group/rest-discuss/message/4732

    I have a hard time seeing how the distinction is useful at runtime (i.e. how the architecture would be better if it could differentiate between a and p), but I find the two categories to a useful starting point in designing. In particular helping myself answer the question “what does it mean to POST to this URI?”

    Meta-comment: it would be useful to know prior to form submission what is going to happen to that URI. Will it be linkified? Will it be subject to line breaks? Should I have used tinyurl.com?

  3. The Worldly Philosopher » Blog Archive » GET and POST: The rest is history Says:

    […] So far, it has been all quite predictable. Now something strange happens. Someone apperantly gets the idea that it would be advantegous to overload the POST method. The POST method already gave the server much responsibilities. For example, it could check the contents of the resource to decide where to place it. But, with reasons not apparantly clear to me, they let go of all semantic constraints of the POST method. POST became a catch-all, a ‘do as you please’ method of sorts. For all HTTP cares about, it’s just a message that’s posted to the resource identified by the URL. [See the posting ‘Post vs PUT‘] […]

  4. jess landis Says:

    is there a way to do a
    method=”post” to page doing the posting meaning i have a form on page form2.php and it is now posting to another php page but i ALSO want it to post to itself. is this possible?

  5. brehaut.net : blog : RESTian Links Says:

    […] PUT vs POST […]

  6. The Cafes » Why REST Failed Says:

    […] PUT is used to create or update a resource at a specific URL. PUT is not safe (it changes or create a new resource) but it is idempotent. That means that if you aren’t sure if a request succeeded, try it again. PUTting the same content twice is not a problem. The end result is the same as PUTting it once. By contrast, POSTing a form twice might mean you’ve bought two copies of Oops!… I Did It Again (and one’s embarrassing enough). […]

  7. License 2 Code » PUT vs POST - Confusion Abounds Says:

    […] In my research on REST this last week, I’ve seen several comments noting confusion on whether to use PUT or POST. After reading several references (Elliotte Rusty Harold, Sacrificial Rabbit, and Mark Baker) , I will attempt to paraphrase the rule as: […]

  8. pauldwaite Says:

    Wonderfully explained. Thank you.

  9. Alex Says:

    Thank You

  10. cbmeeks Says:

    Great article! I’ve never really understood why use PUT or why use POST. To me, they “seemed” to do the same thing. But your explanation made it simple. Also makes me understand why Amazon’s S3 uses PUT instead of POST. Because if you upload a file, and upload it again, it doesn’t duplicate…it wipes the first one out and replaces. Makes sense.

    cbmeeks
    http://www.signaldev.com

  11. Pingala Says:

    I think these methods (from any Requester to any server/service) have to be consistant across broad in order to be operable as expected in a transcational conversation. That is the protocol syntax. Hence, the server/service components and the request components should implement in the same way what RFC 2616 spelled out:

    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. POST is designed to allow a uniform method to cover the following functions:

    – Annotation of existing resources;
    – Posting a message to a bulletin board, newsgroup, mailing list,
    or similar group of articles;
    – Providing a block of data, such as the result of submitting a
    form, to a data-handling process;
    – Extending a database through an append operation.
    The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI. The posted entity is subordinate to that URI in the same way that a file is subordinate to a directory containing it, a news article is subordinate to a newsgroup to which it is posted, or a record is subordinate to a database.

    The action performed by the POST method might not result in a resource that can be identified by a URI. In this case, either 200 (OK) or 204 (No Content) is the appropriate response status, depending on whether or not the response includes an entity that describes the result.

  12. James Crisp - Ruby on Rails, C#, .NET, book reviews, film reviews, mind hacks, Wing Chun and the occasional personal bit. » Practical JRuby on Rails (Web 2.0 Projects) by Ola Bini Says:

    […] REST is only mentioned briefly in a little sidebar, and the description of REST as CRUD is a bit misleading, especially when considering POST vs PUT. […]

  13. Daniel Woo Says:

    Our understanding of HTTP methods for generic Restful web service:
    PUT –> create or update (idempotent)
    POST –> custom actions (like resolve incident, reopen a ticket, activate a workflow etc)
    DELETE –> delete
    GET –> read (safe, idempotent)
    HEAD –> existence (safe, optional)
      
    But Atom Publishing Protocol use POST for creation:
    PUT –> update
    POST –> create
    DELETE –> delete
    GET — > read
     
    Why PUT for Update while POST for creation?
    PUT is create or update in HTTP specification, so it’s best to follow HTTP specification, however Atom uses a different strategy here.
    I think the reason why Atom Publish Protocol uses POST for entry creation is because in most cases this will return a new ID. While this kind of creation is not appropriate for PUT, since PUT must use the record ID at the end of the URL, eg /rest/person/2012, when the ID is an auto-increment ID at the service end, you can not use PUT to create a record. For POST, the URI would be /rest/person and the service end has the knowledge to generate an ID let’s say 2013 and put the new record’s resource URI “/rest/person/2013” in the response header “location”. This exactly follows HTTP spec.
     
    But for those entities you can specify a PK or ID when creating them, and there is no pre-conditions to create them, surely PUT is a better way.

  14. Elliotte Rusty Harold Says:

    Your understanding of HTTP is understandable but incorrect. AtomPub is correct.

    PUT is update or create with a user-supplied URL. POST is create with a server generated URL. There are no custom actions at all. That is one of the key principles of REST. Resolving an incident, reopeningt a ticket, etc. are all defined as one of four actions (PUT, POST, GET, DELETE) on a resource. For instance to reopen a ticket, you might PUT the text “true” to http://www.example.com/tickets/42389349/opened.

  15. PUT or POST: The REST of the Story « Open Sourcery Says:

    […] POST vs. PUT […]

  16. Mark Says:

    If you have to use the analogy:

    PUT = REPLACE (http://dev.mysql.com/doc/refman/5.0/en/replace.html)

    POST = CALL (stored procedures)

  17. Amit Mittal Says:

    Spot ON!!!

    Thanks a lot. Finally I have clearly understood the difference. Most of the explanations I found prior to this focused on ‘Insert’ and ‘Update’ approach to this which I didn’t find convincing enough.

    This one is really awesome.

  18. Dennis Says:

    Well I have a friend who uses PUT to upload highscores from an Android phone. It’s a Sudoku application.

    When I told him he should use post and keep put at Webdav and uploading pages he said it’s up to the server what to do with it. Of course, that’s true.
    But still it’s like using any IP other than 192.168, 10, 172.16-33 in a private network. It will work (until you want to access a real server with that ip, of course) but it’s wrong.

    Could it be possible that some networks’ http proxy servers block the incoming put requests or just throw them away?

  19. Faking PUT, etc. over POST : 9877 Says:

    […] to let my resources handle @PUTs for updates where a URI is known ahead of time in keeping with http://www.elharo.com/blog/software-development/web-development/2005/12/08/post-vs-put/, among […]

  20. PUT or POST: The REST of the Story | ss's space Says:

    […] POST vs. PUT […]

  21. Mark Says:

    Great summary. One question…. if one POSTs and the resource already exists, what is an appropriate response code?? If we wanted to replace the resource we would PUT but in this scenario its not the case.

  22. HTTP Request/Response Introduction | DEVHUB.FM Says:

    […] reading: HTTP 1.1 specification PUT vs. POST HTTP TRACE Vulnerability Blog Post Restful HTTP PUT/POST Article HTTP CONNECT Security White Paper […]

  23. HTTP Request/Response Basics | DEVHUB.FM Says:

    […] reading: HTTP 1.1 specification PUT vs. POST HTTP TRACE Vulnerability Blog Post Restful HTTP PUT/POST Article HTTP CONNECT Security White Paper […]

  24. PUT or POST: The REST of the Story Oct 16 refered by John Calcote | Muruganandhan's Blog Says:

    […] POST vs. PUT […]

  25. Edward Says:

    Nice explanation! Thanks very much.

  26. Max Nanasy Says:

    @Mark
    To borrow from a previous example, a POST that creates a resource would be issued to the URL /rest/person, but the created URL would be /rest/person/2013; therefore, the POST request could not possibly be requesting a resource that already exists, since the POST request is not issued to the created resource’s URL. A PUT, to create a new person or update an existing person, would be issued to /rest/person/2013.

  27. Jiten Says:

    The simple equation is

    PUT: X=5
    POST: X++
    X=5 remains same
    X++ is an incremental for every call

  28. Arnab Says:

    good explanation

  29. What REST PUT/POST/DELETE calls should return by a convention | Ask Programming & Technology Says:

    […] I’ve found a good post describing POST/PUT differences: POST vs PUT But it doesn’t answer my […]