This is a single archived entry from Stefan Tilkov’s blog. For more up-to-date content, check out my author page at INNOQ, which has more information about me and also contains a list of published talks, podcasts, and articles. Or you can check out the full archive.

Deprecating POST, or Maybe Not

Stefan Tilkov,

Benjamin Carlyle makes the case for deprecating post. In a follow-up post, Peter Williams points out the major reason (which is not immediately obvious if you read Ben’s piece without context):

POST’s lack of idempotence has some nasty side effects particularly for what is probably the most common use of POST today, new resource creation. Consider the following scenario, you POST a request to create a new resource but you don’t get a response. It is impossible to automatically recover from this scenario. You cannot resend the request because the new resource may have been created and you just did not get the response and you cannot check to see if the resource was created because you don’t know the URI it would have been assigned if it had, in fact, been created.

Benjamin suggests using PUT to a client-generated URI (based on a GUID) instead, which makes resource creation idempotent (at the cost of a little ugliness in the URI). (The solution suggested by Peter is somewhat strange though: He suggests using a PUT to a “new resource” URI which will return a server-generated URI to which the client PUTs again … I fail to see any improvement over POST).

On March 21, 2007 4:10 PM, Peter Williams said:

The primary improvement is that with the redirected PUT request you never get stuck in a situation from which you cannot automatically recover. If you don’t get a response to the initial put “new resource” URI you can just repeat the request until you do. Once you have that response you know the real URI for the new resource and you can PUT to that URI until you get a response.

On March 21, 2007 4:20 PM, Stefan Tilkov said:

But how is that different from a POST that returns the URI of a newly created resource in a Location: header? If I don’t get the response, I simply issue the POST again and get a new URI. As you say: “Once you have that response you know the real URI for the new resource and you can PUT to that URI until you get a response.” (with the difference that I’d need to do the PUT only if I change something).

On March 21, 2007 6:36 PM, Peter Williams said:

On the assumption that you are not the only person to whom my post was unclear I wrote an follow up, at http://pezra.barelyenough.org/blog/2007/03/better-resource-creation/ , in which I attempt to clarify my position.

On March 21, 2007 6:44 PM, Peter Williams said:

You certainly do a POST request to a new URI service, followed by a PUT to the new URL. The effect would be the same. If feels a little strange to be, though. Perhaps because it is an explicit two step process. In the process I propose it is the second step is implicit and based on normal HTTP redirection semantics.

On March 22, 2007 11:59 AM, Asbjørn Ulsberg said:

The problem with POST today is that there is no unique and stable identifier minted by the client and sent to the server, so the server can’t in any way know if two consecutive POSTs are infact the same POST done twice, or two completely unrelated POSTs. If POST 1 and POST 2 are the same request done twice by a client (because “submit” was pressed twice or because the response on the first POST timed out), then two identical resources will be created.

If, instead, the client PUTs to a unique URI, each PUT to the same URI will create and/or update the same resource, no matter how many times it’s done. That’s not the case with POST. What we could do is introduce a request header on POST that could uniquely identify each POST request and in the cases where two or more requests are just a repetition of the same request, the unique identity would be the same and thus only performed once.

What about using “ETag” for POST requests? It’s pretty easy for the client to hash the content into an ETag and then stuffing that into an header before it’s POSTed to the server. Consecutive POSTs of the same content would lead to the same ETag and the server could thus identify them as the same and not create two resources.