Wednesday 25 July 2012

Go forth and create something RESTful


Every time I speak to someone starting out with REST there seems to be a familiar pattern.
1.  Very likely someone has given you a directive to create something RESTful - with little more reasoning than "because".  (sadly is it uncommon, almost unusual to have a problem and then discover REST as the solution)
2.  You begin to investigate REST and are overwhelmed with libraries, implementations, advice, hearsay, and very little information about why your situation requires REST.  I think everyone should strive to find out "why" their problem needs REST first, but lets summarise by saying reduced client/server coupling (service evolve-ability), horizontal scalability (transparent caching, stateless) as two major benefits.
3.  You start to implement (or are "lucky" enough to have inherited) something that is meant to be RESTful, but clearly lacks some of the advertised RESTful benefits you figured out in step 2.  Go back and challenge step 1 or step 2 as appropriate. 

Here's what happened to me in step 1.
Our group was given a directive of sorts "to provide an interaction architecture with loose client/server coupling".  At this point someone suggested we would benefit from REST.  Being a natural skeptic meant step 2 was quite involved.  We concluded that despite all the libraries, books, and implementations - it appears you have to implement everything yourself or at least put it all together yourself.  Some will say that this is natural because REST is an architectural style.

There are libraries and various standards that will help, but at the moment it is down to you to build your application and ensure that you meet all the RESTful constraints - unfortunately there are just so many ways to go wrong.  Let me try to explain some of the constraints that helped us avoid too many Step 3, Step 2 iterations.

With REST there are 4 key constraints (arguable 5 as Fielding identified 
another after his initial dissertation)

Identification of Resources
Most REST libraries do this pretty well.  For example, JAX-RS uses the @Path annotation to make it easy to bind a method/class to a resource.  Here is a cool list of libraries:  
http://code.google.com/p/implementing-rest/wiki/RESTFrameworks  Your main task is to avoid creating URIs that are Verbs.

Manipulation of resources through representations
Here you may have chosen HAL.  Other good choices might be AtomPub or HTML - depends.  It is quite a lot of effort to standardise and describe a media type to User Agent implementers.  This leads us to choose a media type that is not specific to individual things in your domain, nor something generic such as application/xml as other user agents won't have any idea what to do with your bespoke media type.  Essentially you want to ensure that the client / server can negotiate a good media type, one that suits the purpose of the interaction.  HAL could be good for interacting with application entities, AtomPub could be good for collections of things such as blogs or other structured data. Some other examples could be:  I'd like to add up my list of things - spreadsheet might be ideal (application/vnd.ms-excel) or I'd like to print my list of things - a PDF document might be ideal (application/pdf)

Self descriptive messages
This is one of the nice things that an uncomplicated media type like HAL could give you.  If you describe your resource separately from the view of that resource you open up all sorts of problems.  For example, by having a /metadata resource and a /someentity - you cannot ever really guarantee they are of the same version.  Client or intermediaries could cache your resource or metadata for quite some time.

Hypermedia as the engine of application state
Perhaps you identified HAL links or AtomPub links as a good way to achieve this.  Not the only way I might add, there are good alternatives.  In my opinion, REST is ideally suited to user interaction as you can move your user agent from one application state to another with the user agent responding to each resource to the best of its abilities.  In our earlier example we could use Excel or Acrobat in response to application/vnd.ms-excel or application/pdf media types.  More over, by controlling the user agent from the server, you benefit from some of the key features of RESTs dynamic behavior / upgrades in place (evolve-ability).  (as an aside - Believe it or not Users are pretty smart and know what they want to achieve, systems on the other hand are not smart and don't respond well to interface changes.  I personally clearly separate Interaction from Integration for this reason)  A lot of libraries seem to fall down in this space.  JAX-RS1.1 does not have support for links in the annotations, some people have proposed extensions (http://code.google.com/p/jax-rs-hateoas/)  RestEasy has some support for links http://docs.jboss.org/resteasy/2.0.0.GA/userguide/html/LinkHeader.html  Even as of JAX-RS2.0, the JAX-RS standard and the RestEasy library are still basically "roll your own" as far as links go.

No. 5 Resource generic interaction semantics
Here you've probably chosen HTTP.  Many have said this is the only resource interaction you ever need.  Jury is probably still out on that - see WEBDAV, or even WAKA as other examples.  It is a very well accepted standard and deviating from this will require you to build quite a bit of tooling on the client side and potentially intermediaries.


Take heart.  It's tough job building an architecture according to RESTful constraints.  I'm pretty sure Fielding said "REST is simple, but difficult to get right".

If you found this little blog interesting, perhaps you'll like one of my other blogs on REST in an Enterprise application.  http://aphethean.blogspot.co.uk/2012/06/giving-enterprise-applications-rest.html




http://aphethean.blogspot.co.uk/2012/06/giving-enterprise-applications-rest.html

No comments:

Post a Comment