Software has two ingredients: opinions and logic (=programming). The second ingredient is rare and is typically replaced by the first.
I blog about code correctness, maintainability, testability, and functional programming.
This blog does not represent views or opinions of my employer.

Sunday, June 10, 2012

REST (2): why NOT easy


Continuation of the previous post motivated by my reading of the RESTful Web Services book.

This post is a high level overview of the topic.  In my next posts I will provide more concrete examples of why REST is not so easy.  I am talking about REST in the context of HTTP protocol only.  I assume the reader has basic familiarity what are the 6 HTTP verbs (TRACE and CONNECT do not count ;) and what REST is or at least what is typically painted to be.

When you develop RESTful web services you will be dealing with
  • Resources (think: flight reservation as a resource example)
  • URLs (which are the resource addresses, think:  http://.../{userName}/travel/reservations/flights/{tripName})
  • Resource Representations (for example some XML vocabulary,  think: XHTML document describing flight reservation, seat assignments, etc)
Thus, designing your web service application you will need to think about:
  • How to define URLs (some ways are more RESTful than others)  
  • What standards to use to define resource representations (some standards are more RESTful than others)
In addition, the book identifies following properties which make things RESTful (or as the book calls them ROA-Resource Oriented): 
  • Addressability (measure of how well you can access your resources with URLs, ideally each resource should have a URL) 
  • Uniform Interface (requires that the web service exposes subset of the 6 HTTP verbs and uses HTTP protocol itself to manage resources,  think: GET gets current flight reservation, PUT makes changes to it, DELETE deletes it,  think of using HTTP header and status codes
  • Statelessness (no state on the server, state is in hypermedia)
  • Connectedness (measure how well are your resource representations linked,  think: link or a tags linking to user account with list of other reservations this user has made, link to the airline flight itself, link or form to a ticket resource (to buy the ticket for this reservation), maybe a form tag defining what can be changed using PUT, etc
The first expense of adding REST to your project will be some design time:  (1) split your application into many resources, (2) create URLs for all the resources,  (3) map your problem domain to the Uniform Interface (that includes using standard status codes,  user of more advanced HTTP header stuff),  (4) design your representations (make formatting decisions), (5) connect the resources with some type of hypermedia.

There are 4 big problems categories which make it hard:

PROBLEM 1Tool Support: 
Most tools including Grails or Rails are designed to do something else with ease (to quickly create web apps) and the simplifying decisions which made them successful also makes doing other things (like creating a RESTful web service) hard.  The book lamented about Rails (Grails) has not been covered.
If you are using tools designed for REST (like restlet) this point does not apply.

PROBLEM 2 Finding Standard Vocabulary for Resource Representation:
Some form of XML seem to be best bet, but a vocabulary designed for your problem domain simply may not exist.  Using XHTML maybe a good option.  There may be some relevant microformats for your problem domain.

PROBLEM 3How to implement Connectedness: 
There are very few tools or even standards which could help you to connect your resources.  Connectedness may be the most important part of being RESTful and is the hardest to implement.  The point is that without it REST it is just another API only with fewer verbs and many, many nouns. Sure there is a benefit of not needing to know which verb to use (you have to when using APIs), but there is a tradeoff of having to know many nouns (URLs).   Connectedness implies that REST client can discover the URLs and it does not need to know them and should not be constructing them!

Here is where semantic web becomes important.  Things like microformats, RDF, etc.
XHTML has link and a tags and forms (HTML 5 forms get better).  Atom feeds/APP, etc also define cross linking between resources.  Microformats play a big role in qualifying the 'connections' between resources. 
Future RESTful clients will be able to semantically know the links.

HTTP protocol itself can help in connectedness a bit with its location header and various status codes: 201 (Created), and many in the 3xx (Redirection) range.  But mostly connecting resources will be the job of your resource representations.  No free lunch here. To connect your resources some more serious work needs to be done and you will be looking at exposing you data trough things like Atom feeds.

PROBLEM 4:  Confusion: 
Remember the big picture from my last post?:  APIs are all different, REST is trying to be the same.  The uniformity will not happen if everyone is confused about what REST is, yet claims to support it.

REST is often understood as simply some level of support for the 4 verbs in HTTP (GET, POST, PUT and DELETE).  I maybe repeated myself here, but this trivialized view is demonstrated by most frameworks (including Ext JS, Rails, Grails). Adopting this simplified view point creates confusion and probably impedes support for more meaningful REST functionality these frameworks could provide.

Example:  RESTful JSON. JSON is not connectable (at least not in any standard way), so how can web service be truly RESTful if it is serving JSON only?

This was my high level overview.  Next post will deal with more concrete examples of why it is hard to REST (and maybe easier to stay BUSY ;)

1 comment:

  1. In regard to the connectivity between resources, I wonder if there is a lesson to be learned from LDAP. LDAP connectivity may be implemented with attributes that point to the DN of a referenced resource. This is similar to your idea of embedding hyperlinks in xhtml to implement the connectivity but possibly more standardized.

    In fact, when combined with a JSON interface (http://www.nimbusds.com/json2ldap.html), LDAP looks a bit like a semantic web. Just replace the DN values with structured URLs:

    {
    "objectClass": "Person"
    ,"url": "http://xxx.org/person/id/10"
    ,"id" : 10
    ,"mom" : {
    "objectClass": "Person"
    ,"url": "http://xxx.org/person/id/11"
    }
    }

    or maybe just:

    {
    "objectClass": "Person"
    ,"url": "http://xxx.org/person/id/10"
    ,"id" : 10
    ,"mom" : "http://xxx.org/person/id/11"
    }

    ReplyDelete