In two of our previous blogs we talked about the four different types of HTTP requests that are important when working with RESTful Web Services. In this blog I’d like to take a closer look at the POST and PUT requests; requests that are used to create and update resources. The HTTP 1.1 spec states that
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. […] 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.
and
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 a POST can be used to create and a PUT can be used to create or update, but it’s really not that cut and dry. The REST architectural style doesn’t really mention anything about which should be used for which but the de-facto standard is to use a POST for a create operation and a PUT for an update operation. The main reason for this is idempotency, which is also the main difference between these two operations.
As a reminder, an operation is idempotent if a sequence of two or more of the same operation results in the same resource state as would a single instance of that operation. According to the HTTP 1.1 specification, GET, HEAD, PUT and DELETE are idempotent, while POST is not. That is, a sequence of multiple attempts to PUT data to a URL will result in the same resource state as a single attempt to PUT data to that URL, but the same cannot be said of a POST request. This is why a browser always pops up a warning dialog when you try to refresh a POSTed form. “Are you sure you to buy more airline tickets!?”
Multiple POST requests can cause side-effects such as multiple resources being created.
Let’s look at some example requests.
POST /dictionary
<?xml version="1.0" encoding="UTF-8"?>
<word>
<name>happy</name>
<definition>delighted, pleased, or glad, as over a particular thing</definition>
</word>
This request adds a word, happy, to the dictionary container. Multiple requests could create multiple words and the returned Location URI for the new resources would be different, i.e. /dictionary/happy/1 and /dictionary/happy/2. This happens because with a POST the server is assigning the URI under the dictionary container to insure that the URI is unique to the resource.
PUT /dictionary/happy
<?xml version="1.0" encoding="UTF-8"?>
<word>
<name>happy</name>
<definition>thrilled or ecstatic...now look those up.</definition>
</word>
This request updates the resource at /dictionary/happy with the contents of the xml document in the request body.
So in summary use POST to create a resource by letting the server generate the unique URI and use PUT to update a resource since you already know the unique URI.