Peter Williams has a follow-up post in which he explains his original PUT-vs.-POST idea, which I understand now: The problem with PUT is that while it’s idempotent, it requires the client to know the URL to PUT to, so he suggested a PUT which returns a redirect to some URL created by the server. You then PUT your intended content to the URI returned, and only then the new resource is created.
I believe this is almost a good idea; it violates the original purpose of PUT, though — if I PUT to a URI, I don’t expect it to have different results each time I do so. So my suggestions would be a slightly different approach:
- POST to the
http://example.com/purchase-orders/newURI and have it return
201 Createdand the URI for the new resource in the
- PUT the intended content to the URI, possibly repeatedly in case of error.
Of course this might end up generating “empty” resources, but this is true for the PUT suggestion, too.
Also worth pointing out: In a comment, Asbjørn Ulsberg writes:
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.
That sounds like a good idea, but I believe there’s no way ETags can be created on the client and then sent in a request header. The closest thing to what Asbjørn suggests is probably Yaron Goland’s SOA-Rity, which uses a client-generated message ID.