< Previous
Bully For Torosaurus >

[Comments] (1) Purchase Order Equivalent: Before I left for India, someone emailed me with a random REST question. Yesterday, they re-sent the email with a kind of rude preface that implied I have some sort of SLA for answering peoples' random REST questions. Which I don't! I'm a private citizen who's free to answer a given email whenever I want, or even to never get around to it—the same right I allow the Internet pseudo-celebrities to whom I send email.

So I was kind of cheesed off at this person, but frankly the rudeness worked—I answered the question just to get them out of my hair. The question is, how do you make the creation of a new resource an idempotent operation? Imagine a factory resource that you POST to to create something new. Typically, if you send the same POST request twice, you'll get two new resources. How do you make it so that the first request creates a new resource and the second request fails?

The short answer is to use POST Once Exactly. I mention POE in the REST book, but POE never made it out of the Internet-Draft stage, and I can't even find the Internet-Draft at Mark Nottingham's site anymore. Besides which, the email message described something similar to POE as an option, but wanted something simpler. So here's something simpler, for some value of "simpler".

When you buy (eg.) computer hardware from NewEgg, they give you a space for a "purchase order" along with shipping address etc. This is for use when you're buying stuff in a commercial context. You can put whatever you want in that space. The purchase order is a key into your company's purchasing system. It's meaningless to NewEgg.

Newegg doesn't use the purchase order for anything, they just put it on the invoice for your convenience. But in theory, they could keep track of the purchase orders you've used. Since they know which orders are yours, when you place a new order the site can run a quick check to see if you've used that purchase order before. If you have, they can stop the purchase from going through, since you're probably trying to process the same purchase request twice.

So the simpler solution is. You're defining the media type or the form describing what the client is supposed to POST to the factory. Include a slot for a "purchase order". This is a random string chosen by the client whose only purpose is to uniquely identify a resource to be created. On the server side, reject a POST request that uses a purchase order already used by this client ("this client" distinguished from other clients by the authentication credentials). Now the POST request is idempotent: sending it 10 times is the same as sending it once.

I call this strategy "Purchase Order Equivalent", or POE. Thoughts?

Filed under:


Posted by Nathaniel at Tue Aug 10 2010 01:37

Requiring a strong concept of "this client" seems potentially over-complicated -- why not just tell clients to use UUIDs?

Of course, you'd need a cryptographically strong RNG to generate the UUIDs, which might be prohibitive in some cases.


Unless otherwise noted, all content licensed by Leonard Richardson
under a Creative Commons License.