Harry Pierson: "Given that POST isn't Given that POST isn't naturally idempotent, I think it's kinda surprising that new resources are created in AtomPub by POSTing them to a collection rather than PUTting them to a specific URL. RESTful Web Services specifically points out that PUT is idempotent, so I wonder why AtomPub uses POST. I'd guess most AtomPub implementations (aka blogs) aren't much concerned about ensuring Exactly Once. If an blog entry gets posted twice, you delete one and go on with your life"
POST allows the server to define the URL space as it sees fit, which is neccessary for some (a lot of) services. Less important, it also avoids an accidental update, where a client PUTs with the intent of creating a new resource to a URI that already exists - "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" [RFC2616].
When using POST, the URI you POST to identifies something that will handle the entity being sent (in our case, Atom entries), not the entity itself. This is one reason why it historically gets used for forms handling, gateways and RPC (everything identified in an RPC design is a handler).
"However, if you wanted to use AtomPub and ensure Exactly Once, you can use the fact that Atom entries must contain exactly one ID element which as per the spec must be universally unique. From reading the Atom spec, the ID element seems primarily designed for Atom feed consumers, but AtomPub servers could also use it as an "idempotence identifier", similar to how MSMQ uses the message ID. If you end up with multiple entries with the same entry ID, discard all but one."
Well, that assumes you trust your clients, or more subtly, that they are defect free and will not interfere with each (neither assumption carries on the internet).
"So by creating a unique identifier on the client side and logging that identifier on the server side, we can make any REST service idempotent."
This will only work if you can gurantee two clients will not send the same ID at the same time where "same time" means within a server transaction window. It's going to be simpler and more robust to let the server name them, even in a load balanced scenario. URIs are cheap to mint, coordinating clients over time less so.
Like most messaging systems (and this includes moving paper business documents around), the answer tends to be two identifiers, one set by the recipient and the other provided by the sender ("our ref", "your ref"). In a HTTP/REST scenario then, the ideal setup is to have the server give the message exchange itself a URI which is different from the thing being sent. That way you or third parties can track the exchange state (exchanges are stateful after all). Indeed, you can probably get away without identifying the thing you're sending - in electronic messaging, mostly you want to know where things are at, not what they are. IME there are 3 resources in play in a HTTP client/server messaging scenario:
- the service that handles the sent message
- the message
- the state of the message
2 Comments
You could also use ETag validation on the create-styled PUTs to ensure uniqueness. "if-none-match: *" et al. I don't suppose the current AtomPub spec rules out this kind of behavior, does it?
Patrick, far from it:
http://bitworking.org/projects/atom/d...