Imagine a web-application storing some data-resource with some id which stores three attachment (e.g. pdf) per datum.
The URL scheme is
data/{id}/attachment1 data/{id}/attachment2 data/{id}/attachment3
An RESTful API exists for the attachments providing GET/PUT/DELETE operations implementing CRUD operations on the server side.
Letting the id be 123, I would like to perform an operation where
GET file/123/attachment1
returns the a new attachment)GET file/123/attachment2
returns 404)The update should be atomic - the complete update is performed by the server or nothing at all.
Applying a simple PUT file/123/attachment1
and DELETE file/123/attachment2
is not atomic, since the client could crash after the PUT and the server has no hint that he should do a rollback in this case.
So how do I implement the operation in a RESTful way?
I've thought of two solutions but they both do not seem to be 100% RESTful:
While this ensures atomicity, I doubt this is RESTful since i overload the PATCH method using different parameter lists, which violates the uniform-interface constraint.
DELETE transaction/data/123/attachment2
) and communicate the commit of this version of the resource to the server via a PUT on transaction/data/123. This ensures atomicity while a have to implement additional server side logic to deal with multiple clients changing the same resource and crashed clients which never committed.While this seems to be consistent with REST it seems to violate the contraint of statelessness. The state of the transactional resource is not service state but application state, since every transactional resource is associated with a single client.
I'm kind of stuck here, so any ideas would be helpful, thanks!
You want to use the second option, the transaction option.
What you're missing is the creation of the transaction:
POST /transaction HTTP/1.1 301 Moved Permanently Location: /transaction/1234
Now you have a transaction resource that is a first class citizen. You can add to it, delete from it, query to see its current contents, and then finally commit it or delete (i.e. rollback) the transaction.
While the transaction is in progress, it's just another resource. There's no client state here. Anyone can add to this transaction.
When its all done, the server applies the changes all at once using some internal transaction mechanism that's out of scope here.
You can capture things like Etags and if-modified headers in the transaction sub actions so that when they're all applied, you know that something didn't change behind your back.
Very interesting question. A C.S. professor at university of Lugano (Switzerland) wrote some slides about this situation:
http://www.slideshare.net/cesare.pautasso/atomic-transactions-for-the-rest-of-us
However I'm not really sure that the solution he provide is totally RESTful because it doesn't seem really stateless on the server side.
Being honest, since the transaction itself is composed by multiple states, I don't think there can be a totally RESTful solution for this problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With