Continuation of the previous post motivated by RESTful WebServices book.
In the previous post I have tried to identify the elements of REST and
pointed out general problems around software development of RESTful web services. I am
considering REST based on the HTTP protocol only.
REST is important concept and can yield many benefits to applications which decide to be strictly RESTful.
REST is important concept and can yield many benefits to applications which decide to be strictly RESTful.
Here is a more low level detailed list of REST things which are not very easy to do. (It is my private what I can screw up (or I did screw up) and where I should be careful list):
URLS
- Constructing URL is NOT client job: I believe we will see very few applications where this is met and it is obviously hard to achieve. It requires excellent 'connectedness'. Designs where client needs to know how to construct URLs are not RESTful.
- ? Restrictions: Except for few spelled out exceptional cases using ? is not fashionable any more. Unfortunatelly ?-marks are so easy to use: just throw some parameters in and you done, you never have to rethink you URLs, you can simply add stuff to them to piggyback new functionality. If you do that it is not RESTful.
- No Database IDs: Rails with ActiveRecord and Grails with GORM make using IDs easy. These are not very useful especially when the service is not well connected. Imagine a fantasy Active Directory exposing REST interface, you want to get a phone number for jsmith. Would you prefer to issue a GET to: .../users/jsmith or .../users/2001234? Frankly, the second URL format is useless, yet you will find it in most Rails or Grails projects which claim RESTfulness and in fact this is what you get if you use Rails REST scaffold.
- Lack of support for templates: (example: /users/{userId}/posts/{topic}). Few tools support templates. GRAILS has UrlMapping file, but there are limitation to it as well. I believe Rails, as I understand it, is more limited than Grails.
- No Verbs please: This may require extra effort and even rethinking of what are your resources. URLs represent resources, so URLs containing verbs (.../myserver/mydatabase/runDefragmenter) are not RESTful. How about POSTing to: .../myserver/mydatabase/defragjobs instead? API-like thinking is very much ingrained in us. API and REST should not be used in the same sentence (unless you think of the uniform interface).
Uniform Interface
HTTP protocol is the base for achieving the uniformity. This goes beyond the 4 (or 6, or 8) HTTP verbs and
requires understanding of the HTTP protocol itself with advanced use of headers, status codes, etc. Defining HTTP protocol and explaining how it
applies to REST is not what I want to do here.
I just want to point out that RESTful is not RESTful without it. Here are some examples.
- Status Codes: Example 1: consider a PUT to a URL representing a resource with unique constraint on its name. The PUT tries to rename the resource but a resource with the new name already exists. I bet many apps will simply return status 500. Correct code should be: 409 (Conflict).
- Example 2: As above, consider a PUT request to rename a resource and assume that resource name is
part of the URL. I bet may web services
will simply return 200 and a new representation leaving to the client to
'construct' the new URL. This is not
optimal use of HTTP protocol and is not RESTful.
- Other Header Stuff: There is a bit to learn there and this will probably be overlooked by many developers writing RESTful apps. This could create lack of consistency.
- Uniform Interface vs Serving Web Pages to the users Typical 'MVC' web frameworks have you focus on flow of web pages. Programming REST Uniform Interface is different. Making both pieces of logic coexist is harder than it looks. I will explain more in the next post.
Formatting resource representations
Standard Interface helps but its benefits are less inspiring
if REST client coded by someone else has no way of understanding the content.
Coming up with a standard vocabulary for your problem domain
may be hard, one may simply not exist.
Adopting something like Atom Feeds or XHTML may seem artificial or
awkward (yet often are the best choices you have).
Grails or Rails make it easy to spill out XML or JSON, but this
will not be any standard vocabulary and your resources will not be connected.
Even much simpler problem of assuring that error messages are served in a format expected by the clients are often surprisingly easy to overlook and may not so easy to implement.
Statelessness.
REST has no place for cookies, session objects, etc. Simply
put: don't claim your app is RESTful if you store server state between HTTP requests. Hypermedia
is the engine of application state in REST.
I may be opinionated on this but to me it is not just about
REST: if you programming web app and use
session object, you should rethink your design.
But then since people use server side state on web apps a lot, they must
be finding this technique convenient and the benefits of being stateless not
worth the extra effort to them.
My personal opinion is that a possible exception to this
rule is use of some standard security infrastructure (like Spring Security)
which may have stateful implementation and you have no control over it. This still would violate REST, but you may have not much choice.
POST is the worst of
the 6 verbs.
I you can avoid using it you should. But that is obviously not easy.
I am not elaborating on this one ... go and read the book ;)
Connectedness.
If the client has to construct URLs then the server is not
RESTful. Ability to discover URLs is
what differentiates REST from API.
I wrote a bit about it in my previous post. This is the hardest thing to do right and
will impact your decisions on representation formats. This topic is out of scope for this post.
No comments:
Post a Comment