POST vs. PUT

This morning, Matthew writes about building RESTful services with the Zend Framework. I have a lot of thoughts on his post, and I might blog more about it later, but right now, I want to focus on David’s comment:

I think the next thing you should cover is how to retrieve put parameters and maybe even attempt to start a discussion on the different school of thoughts about POST vs PUT (Especially in the PHP world).

I know I’m even guilty of mentioning different schools of thought on POST vs. PUT in my talks, but the truth is that REST doesn’t specify what to use for what actions. These are defined by HTTP and not by REST.

Roy Fielding has this to say about the use of HTTP verbs in RESTful applications:

Some people think that REST suggests not to use POST for updates. Search my dissertation and you won’t find any mention of CRUD or POST. The only mention of PUT is in regard to HTTP’s lack of write-back caching. The main reason for my lack of specificity is because the methods defined by HTTP are part of the Web’s architecture definition, not the REST architectural style. Specific method definitions (aside from the retrieval:resource duality of GET) simply don’t matter to the REST architectural style, so it is difficult to have a style discussion about them. The only thing REST requires of methods is that they be uniformly defined for all resources (i.e., so that intermediaries don’t have to know the resource type in order to understand the meaning of the request). As long as the method is being used according to its own definition, REST doesn’t have much to say about it.

The POST vs. PUT debate, however, does rage on in different communities, and some protocols have defined their usage. For example, the Atom Publishing Protocol (RFC 5023) explicitly states in section 4.3 that “POST is used to create” and “PUT is used to edit.”

The important thing to note is that REST doesn’t care how the HTTP verbs are used, as long as they are used properly according to how they are defined in the protocol you are using.

For those interested, HTTP (RFC 2616) defines POST by saying:

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.

PUT is defined as:

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.

With this line of thinking, you might come to the conclusion that POST is used for creation of a subordinate resource, while PUT could be used for both creation or modification of a resource. The important distinction is that POST identifies the resource for which the entity should be considered a subordinate; PUT does not.