Reliable HTTP POST

A couple of ideas I don’t want to lose regarding how to POST reliably in HTTP :

Mark Nottingham and Paul Prescod recommend similar solutions. The server gives out unique URIs for handling POSTs. These URIs accept only a single POST, preventing multiple POSTs from causing duplication.

Mark suggests that a second POST respond with status information:

If the server receives more than one POST to any particular ‘action’ link, it should generate a message saying “This order has already been submitted,” perhaps along with a summary of the order and its status.

Paul takes a different approach:

The response of subsequent POSTs should be the same as if there had been only one POST so that the client can get the correct response even if there is a network outage in the middle of the first response.

John Beatty has a nice follow-up article in which he points out that this kind of behavior might not be RESTful. The server has to remember ephemeral application state (the request identifier) from a previous request in order to service the current request.

Mark Baker weighs in:

There are actually ways of doing id generation on the server and still having it be stateful [I think Mark means to say “stateless” here. –mgarland] though; generate a URI on the server, and pass it to the client with the intent that the data be PUT to that URI. That way you get to use the idempotence of PUT, though at the cost of another round trip. But that could be amortized by sending a batch of URIs which can be reused as the client sees fit.

This puts the state back on the client in the form of a URI. Presumably, the server can extract enough state from the URI to serve the resource.

I toyed with the thought of using GET to find the unique URI. Then POST to the unique URI creates the resource at the URI, at-most-once, and must occur before PUT, GET, or DELETE to that URI make sense.

But I suspect that doing so may lead to race conditions that require the client to two-step with (409) Conflict, and it might also violate the definition of POST:

accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line

I’d love to hear informed opinions on this. For now, I’m POSTing to get the unique URI and PUTing the desired state.

Comments are closed.