I realize that the title of this posting might be a bit off-putting for non-RESTafarians, but it’s about a topic that matters to anyone building an application that uses simple web standards for updates.
Background: how REST usually works
There are two HTTP methods that you can use for adding/updating information on a web site:
- PUT
- PUT, when you know the address (URL) of the thing you’re adding/updating.
- POST
- POST, when you don’t know the address of the thing you’re adding/updating (you’re implicitly asking the server to assign a URL for you).
Since PUT refers to a specific URL, people say that it’s idempotent — that is, if you repeat the same operation three times, it won’t create three separate resources on the server (I’ve simplified the HTTP headers a fair bit in these examples):
PUT http://example.org/greetings/resource01.xml <greeting>Hello!</greeting>
PUT http://example.org/greetings/resource01.xml <greeting>Hello!</greeting>
PUT http://example.org/greetings/resource01.xml <greeting>Hello!</greeting>
The result is just one resource at http://example.org/greetings/resource01.xml.
POST, on the other hand, sends the request to one URL (or other address) that will place the resource at a different URL. If PUT is like placing the resource in a file yourself, POST is like handing it to a file clerk. As a result, POST is not guaranteed to be idempotent:
POST http://example.org/actions/add-greeting <greeting>Hello!</greeting>
PUT http://example.org/actions/add-greeting <greeting>Hello!</greeting>
PUT http://example.org/actions/add-greeting <greeting>Hello!</greeting>
In this case, HTTP itself makes no guarantee that this three-time repetition won’t result in representations of three different resources with the same content, say http://example.org/greetings/resource01.xml, http://example.org/greetings/resource02.xml, and http://example.org/greetings/resource03.xml.
Self-identification
So that’s it, as far as HTTP goes, because HTTP is just a transport layer — with a few exceptions (like re-encoding text files), it doesn’t care whether you’re using it to send a picture, video, web page, or XML file. Because HTTP doesn’t know anything about your resource, it can’t make any guarantee about the idempotence of POST.
Let’s say, however, that you’re designing an XML-based web application where every resource has its own, internal unique identifier. To take a simple example, let’s use ISO 3166-1 alpha2 country codes, such as “US” for the United States or “DE” for Germany. Your XML files always contain the identifier in a place that the application can find it:
<country ident="CN"> <name>China</name> <population>1338299500</population> <land-area unit="km2">9640011</land-area> </country>
If your web application has a fixed URL scheme based on the ISO 3166 code, it will create this resource at (say) http://example.org/countries/CN.xml when you POST it. If you POST it a second time, it won’t create a second copy of the same information, because it has a fixed mapping between the code “CN” and the URL, and knows that this is a new representation of the same resource. In other words, while HTTP itself can’t guarantee idempotence for a POST operation, the web application can.
So now what?
So for a web application like this, does it make sense to have both POST and PUT operations? RDF fans would say clearly “yes”, since they would consider the URL — not the ISO 3166 code — to be the resource’s identifier, and I feel strong sympathy with that approach (URLs make great global identifiers for things). There is, however, a down-side. Let’s say I’m reading data from a legacy system that doesn’t know or care about URLs. Does it make sense to force that system to duplicate my URL-construction algorithm, and know to PUT its updates for China to http://example.org/countries/CN.xml, for Canada to http://example.org/countries/CA.xml, etc.? Or does it make sense just to let the client POST to a single URL, knowing that the application will enforce idempotence based on the domain-unique identifier in the XML file?
I actually haven’t made up my mind on this point yet. As I wrote in a 2005 posting, real-world REST applications generally stick to GET for retrieval and POST for creation/updating/deletion, however inelegant that approach may be. I hope things have improved in the last 6½ years, but I’m not confident that they have.
What do you think? Is allowing both POST and PUT unnecessarily complicating the interface for the sake of RESTful purity, or is using only POST for creation and updating breaking the implied contract of HTTP and risking confusion among users?
I’ve written a sonnet, and I think it’s very good. Now I’d like to get paid for it so that I can quit my job and live off the revenue. Any suggestions?


