Poking at ROA
A while ago, I criticized GData’s batch mode:
Anytime you find yourself adding words like “operation” to your representation, you’ve violated one of the core RESTful HTTP principles, which is that the intent should be communicated using the HTTP verb.
Erik Johnson wrote up a reply on his blog:
I’m a big fan of ROA, but I’m worried that ROA fundamentalism will create a quagmire (shared by SOA) where all advice seems to be about what not to do. ROA makes it easy to bind the HTTP verb with your intent, but it doesn’t require you to do so. If I define a format for a message that can contain multiple “intentions” and then expose POST endpoint for processing messages, have I broken some Law of ROA? I don’t think so.
I think Erik is right in that we should maybe focus more on what to do instead of what not to do. But first, let me explain my problem with the GData approach in more detail: One of the constraints of REST is the uniform interface, and HTTP mainly implements this constraint with its four common verbs - GET, PUT, POST, DELETE. Each of these have meaning beyond “move bytes from here to there”: A GET is safe and idempotent, PUT and DELETE are idempotent, there are no guarantees about POST. What I don’t like about the GData batch approach is that it uses POST to send a request body that contains sections with “operation=’delete’”, “operation=’insert’” and so on — i.e., it mixes up the meaning of the verbs with an overridden meaning in the content.
I would like an approach much better that used DELETE, PUT and POST to update a collection resource, possibly with some query string added, to achieve the same, i.e. in some pseudo-syntax (I’m too lazy to lookup GData query format):
PUT /entries?month=June
<entries> ... </entries>
(with DELETE working the same way), and a POST to the collection root (e.g. entries) to add a number of entries in one step. (Of course this is pretty simplified — there are still a lot of issues left to resolve, such as the correct response and response codes.)
This way, it would no longer be possible to insert, delete and update a lot of entries in a single step — you’d have to make it three steps, which doesn’t seem a big deal from my point of view, and would ensure that you could do the DELETEs and PUTs idempotently.
But I haven’t tried this out, so in the end it may turn out that Erik is right — the use of POST yields no guarantees, so maybe (at least in this particular respect) the GData approach might be the more pragmatic choice (and not as bad as I initially thought).
“you’d have to make it three steps, which doesn’t seem a big deal from my point of view, and would ensure that you could do the DELETEs and PUTs idempotently.”
If you can convince the “client” that they have to invoke your service 3 times then it isn’t a big deal. But how many integrators care about the purity of REST to buy that they couldn’t just POST all they want done? :) Half the battle is building the service RESTfully, the other half is getting people to consume it the way YOU (or me) believe it should be consumed.