Sunday, August 23, 2009

CRUD vs. HATEOS

Of late there has been a few blog post on HATEOS vs. CRUD as the underlying architecture (if I can say that) for RESTful services. I think it was started by Arnon's post [http://www.rgoarchitects.com/nblog/2009/06/23/CRUDIsBadForREST.aspx]. I know infoq has a summary somewhere but I couldn't find it right now. [Please read Arnon's post for background on HATEOS vs. CRUD]

Here's my contribution on the whole thing.

First of all, we should know that what Arnon suggested was not "CRUD is evil and should rot in garbage landfil somewhere ... " or anything near that. [So the CRUD proponents should not get so worked up about it]. He is suggesting that CRUD is OK but you can do better. Especially if you need control - I.E. if the business process that you run is super critical, like some baby seal is going to be devoured by Bernie Maddox if you don't execute things in order, than HATEOS is the way to go.

In fact, HATEOS is just that : RESTful workflow

Note to self: investigate if HATEOS can replace BPEL just like REST replaces SOAP

Now, I believe that HATEOS is superior to plain old CRUD because of one thing:

Long Running Transaction (LRT)

LRT is a way to do transaction in a long running processes (typically, a transaction that involves people somewhere should be considered long running). In LRT, due to time constraint, it is impossible to lock an object (a database row, a resource, etc.) for the whole transaction. ACIDity is assured only on single operations but not the whole transaction. What happen when failure occurs? Well, you run another ACID operation to undo transaction.


Quoting wikipedia : "Long-running transactions are computer database transactions that avoid locks on non-local resources, use compensation to handle failures, potentially aggregate smaller ACID transactions (also referred to as atomic transactions), and typically use a coordinator to complete or abort the transaction. In contrast to rollback in ACID transactions, compensation restores the original state, or an equivalent, and is business-specific. The compensating action for making a hotel reservation is canceling that reservation, possibly with a penalty."


Example:

Given an e-commerce business process:

If the user cancel the order mid-way:




... We might need to fire another business process to compensate the original business process.



Now, here is where HATEOS really shines: Note that the compensation business process in this example is going to be fired by say, a call center receiving the user's cancellation request whereas the "Item has arrive" activity is probably going to be fired by some delivery service.

When the call center request the state of the business process, we will send an xml object and also includes a link to cancel the order.

When the delivery service request the state of business process, we will send an xml object and also includes a link to indicate that delivery is completed.

With plain old CRUD on the other hand, well, you will not know what API to invoke and what are our options. Heck, user might even invoke things that they should not.

Also note that, each activity within the business process actually has a corresponding "compensation" activity. This compensation activity will certainly undo the real business process activity. A link to the compensation activity is always available at each business process activity and can be invoked if needed. Unlike plain old CRUD where the user has to figure out at each stage of the business process what to do in case things go wrong, in HATEOS the user do not have to figure out what to do in case of exception: just invoke the compensation URL and all should go well.