02/25/09 :: [REST] Are you Link'in? [permalink]
I have been thinking last week about a potential implementation of HATEOS that was not CRUD oriented. As I mentioned several times, CRUD introduces the worst coupling possible between a consumer and a provider, not to mention that most providers would never trust a consumer to CRUD it in the right state. Just ask the Societe Generale how much money you can loose when you let people CRUD around your systems.
So I will take off CRUD off the discussion for the rest of this post, if all you want to do is CRUDing, JAX-RS lets you do that copiously...
Here is my typical real world example that I like to use to test concepts. It shows two resources, a PO and a shipment which each have a lifecycle as represented below as a series of states and transitions. Transitions occurs as actions are invoked on the resource.

A REST implementation typically uses a POST of a resource to the target resource. For instance, in order to transition to the submitted state (from created which is itself achieved with a PUT), you would POST a submission, in order to transition to paid, you would POST a payment, and so on...
This is based on RFC 2616 which defines POST as follows:
"The POST method is used to request that the origin server accept the entity enclosed in the request as a new subordinate of the resource identified by the Request-URI in the Request-Line." (trans.: if you create a new resource "inside" an existing URI, use POST: this applies if you are doing something like creating a new resource and you don't know what its URI will be).
The problem I have had with the claims made by the RESTafarians is that HATEOAS (HyperMedia as the Engine of Application State) is enough to manage "application" state. Of course they should define what "application" means in a "connected system" as there should not be really any application boundaries, but let's pass on that, one day they'll wake up and realize how much BS the (other) REST is as a programming model, again, nothing I say pertains to Roy's REST.
Stefan for instance has been claiming that all he has to do is to "POST" resources to advance the state of a process. He has never provided an example to show how this would really work. Savas and Jim don't even understand the difference between a resource lifecycle and a business process, so it is hopeless to think they would successfully explain how to implement a process-centric scenario in REST.
The best I can come up implementing an action that follows the POST specification, (without CRUDing with a PUT of course) and therefore without changing anything to the target resource, is to have predefined links in the parent resource. So the PO representation would look like that once it is instantiate
<po>
<link rel="canonical" href="http://www.myco.com/orders/123" />
...
<link rel="submission" href="http://www.myco.com/orders/123/submission" />
<link rel="payment" href="http://www.myco.com/orders/123/payment" />
<link rel="shipment" href="http://www.myco.com/orders/123/shipment" />
</po>
As "action" resources get posted the links in the target resource become active. They would otherwise return a 404 error. This model has a nice side effect, the red arrows in the figure above that represent state alignment messages, can be implemented without exchanging messages until that information is needed. Of course, once you need the information you must now navigate the link but isn't it the premise of HATEOAS since REST can't do joins? HTTP is no XQuery, but who cares right? So all is well in a perfect world as our old friend Voltaire would say. We can all go back and landscape our backyard.
Well, not quite. The first problem is that you have to navigate all the links to figure out what is the current state of a PO. In particular this process has to occur each time an action is "POSTed". The second problem is that links are "unordered" in a resource representation. Again, REST was designed for humans, even if Roy kind of denies it, and humans can make sense of everything they can process (yes link represented in a foreign language may be as dead as static text). So unless you share this ordering information out-of-band or come up with a state machine microformat you can't really figure out which state this resource is in.
Overall it looks to me that REST would gain immensely by defining a proper action mechanism (and while they are at it, inter-actions and trans-actions, not to mention a contract and versioning, but that's still a touchy subject despite Subbu's work). Today the RESTafarians are either CRUDing or wiring POSTs directly to the target resource, via a command pattern, in complete violation of the POST semantics.
Guys, more semantics are necessary, be it for actions, or, for instance, "joins" that would bring information automatically into a consumer via HATEOAS links without having to navigate the corresponding link. Subbu seems to be working along these lines, I wish he would go all the way. There is simply no other way.
Now, I apologize that I have trouble to understand the full meaning of Roy's definition of a REST API. So maybe I am completely off base here. Maybe he considers CRUDing acceptable, at least I could not rule it out from his definition.