I've slowly been appreciating the wisdom in using REpresentational State Transfer (REST) as the architectural style for building services on the Web. My most recent influences have been Nelson Minar's ETech presentation entitled Building a New Web Service at Google and a discussion on the XML-DEV mailing list last week.
The REST architectural style was first formally defined in Chapter 5 of Roy Fielding's Ph.D dissertation. It's principles are succintly distilled in the Wikipedia entry for REST which currently states
REST's proponents (sometimes referred to as RESTafarians) argue that the web has enjoyed the scalability and growth that it has as a result of a few key design principles:
-
A fundamentally stateless client/server protocol: each HTTP request/response pair is complete in itself, and participants are not required to take additional steps to track states (though in practice, many HTTP servers use cookies and other devices to maintain a session state).
-
A limited number of well-defined protocol operations: HTTP allows very few verbs, the most important of which (for REST) are GET, POST, PUT, and DELETE. These correspond fairly closely with the basic
CRUD
functions required for data persistence.
-
A universal means of resource-identification and -resolution: in a RESTful system, every piece of information is uniquely addressable in a single namespace through the use of a
URI
.
-
The use of hypermedia both for application information and application state-transitions: the resources in a REST system are typically
HTML
or
XML
files that contain both information and links to other resources; as a result, it is often possible to navigate from one REST resource to many others, simply by following links, without requiring the use of registries or other additional infrastructure.
These principles can be further distilled to the simple phrase, "Just use HTTP". However the problem with this is that lots of people actually don't use HTTP correctly. This ranges from the fact that many HTTP-based systems don't support the DELETE and PUT to the fact that many services based on HTTP ignore the specification that HTTP GET requests should be idempotent and safe. About the latter issue, the HTTP specification states
9.1 Safe and Idempotent Methods
9.1.1 Safe Methods
Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
...
9.1.2 Idempotent Methods
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.
There are a number of reasons for HTTP GET requests to be both idempotent and safe. Being idempotent means that various caching systems between the user and the web server from the browser cache to caching proxies can cache the request without worry that the web server was supposed to service that request. And as Sam Ruby pointed out in his post AJAX Considered Harmful being safe means unsuspecting grandmothers and bots everywhere cannot be tricked into modifying online databases simply by following a link.
However a number of web services that have been held up as examples of RESTful APIs actually violate these principles. These include the Bloglines sync API, the Flickr API and the del.icio.us API.
-
An example of where the Bloglines sync API uses HTTP GET requests in a way that is not idempotent or safe is the getitems method which has a parameter to "mark unread items as read".
-
An example of where the Flickr API uses HTTP GET requests in a way that is not idempotent or safe is the flickr.photosets.delete method which deletes a photo set.
-
An example of where the del.icio.us API uses HTTP GET requests in a way that is not idempotent or safe is the http://del.icio.us/api/posts/delete function which
deletes a post from delicious.
This isn't to say all popular web services held up as RESTful APIs actually aren't. The Atom publishing protocol is an example of a RESTful API that actually honors the principles behind HTTP. However there are a number of plain old XML (POX) web services which people have begun to conflate with RESTful services which led to some confusion on my part when I started trying to figure things out in this space.
A good place to start when deciding to design a RESTful system is Joe Gregorio's article How To Create a REST Protocol.