RESTful systems are by definition supposed to be based on the architectural style of the Web; however, there is one big fat glaring difference between the Web and almost all of the other systems out there that claim to be RESTful. I’m not talking about use of methods or any other aspect of HTTP. I’m not talking about the structure of the URIs, the resources in the system, or even whether or not the representations contain links. Many systems that can honestly claim to be at Level 3 of the Richardson Maturity Model have this deficiency.
I’m talking about over-constrained, service-specific hypermedia formats that precisely represent a service’s resources and workflow. It’s hard to think of this as a “problem” — it’s what we’re used to doing in software interfaces. But this is certainly not how things work on the Web. Here we have a single format, HTML, used by a wide variety of services: Google, Facebook, Amazon, etc., that all do very different things. The markup language is not designed around the semantics of any of the resources exposed by these services. There is no <book> element used to represent a book on Amazon.com. The Web’s interface is uniform not only because of HTTP but also because of HTML.
Think of it this way: the fact that HTML is able to describe a wide variety of services not only allows a single client to work with the limitless set of sites on the Web, but also allows a single service to evolve. A site can change itself from one of the services describable by HTML to another without requiring the browser to be updated. However, if a hypermedia format is only able to express a very constrained range of services, then service evolution becomes impossible. If you provide a service for “sprocket management” and your hypermedia format is defined in terms of sprockets, collections of sprockets and link relations describing all the supported actions one might take on sprockets, then it’s hard to see how it could be used for anything else in the future.
You may be wondering how exactly you go about broadening the range of your service’s hypermedia format. Sure you can generalize the format (maybe a sprocket is just a type of widget and instead of sprocket collections, you can just have a generic collection element) but that will only get you so far. And more importantly, most folks don’t have the precognitive abilities required to know where their service is going to evolve to in the future. Format extensibility isn’t the answer either: clients would still need to be adapted to any extensions required to support changes to a service.
We can look to the Web for a strategy to deal with this.
HTML is the language of the browser; it is the lens through which browsers see all resources. Services adapt their information and workflow descriptions (resources) into documents in this language (representations) when working with browsers. The HTTP Accept header tells them that they are working with a client that speaks the browser’s language — a browser or some other client, like an indexing spider that would like to see the resources from the browser’s perspective.
When building RESTful systems for other domains, why do we make the hypermedia format specific to the service? Instead, we should be defining hypermedia formats around the clients — if the goal is to allow the client to interact with the widest range of services possible, then it makes sense to use a format that is designed around the client semantics and bounded only by the capabilities of the client.
At first glance this seems to be binding the service to a specific client — but not completely due to the declarative nature of markup and the Principle of Least Power. Other, secondary types of clients like indexing spiders are able to analyse the markup and understand what it does to provide other capabilities such as search. So really the service is bound to the ecosystem of clients that understand that markup language. But still, this model does limit the clients that can be supported with a single markup language.
This is where the separation of resources and representations, and Content Negotiation (conneg) come into play. A single resource can have multiple representations. They can have a separate URIs or share a single one (using the conneg features of HTTP), but either way a client is able to get the resources represented in a format it supports. By supporting multiple hypermedia formats, your service can cater to multiple classes of client simultaneously. Support for new formats/clients can easily be added without disrupting existing ones.
For example, say that you are building services within a bank. Rather than designing a single hypermedia format around the resources and services such as accounts, balances and financial transactions, design (or re-use) separate formats for each type of client. The teller terminals would likely use HTML, the ATM machine might also use HTML or something similar to deal with the specifics of the interface, a hypermedia format might be designed for automated cheque processing machines. Inter-bank transactions are a tricky point — this might require a format designed around accounts, transactions etc. but this should be at least customized to the specific inter-bank use cases. However, an alternative approach might be to support multiple hypermedia formats at the inter-bank boundary for the specific client types. (Ok, so I’m not in banking myself, so maybe I’m a little off base here on the specifics but I think the principle is sound. If you want examples from my domain, I can simply refer you to VoiceXML and CCXML.) By customizing the hypermedia to the capabilities and needs of the individual classes of client, you provide the services with the ability to change and grow.
This model is based on the assumptions that the services outnumber and will evolve more quickly than the clients and that updating clients is more difficult/expensive than updating services. HTML and browsers do evolve — but there are far fewer browser implementations and versions of HTML than there are services (never mind versions of those services). Also, it is much more difficult to get millions of users to update their browsers than to update your web site. If these assumptions don’t hold for your domain, maybe designing your hypermedia format around your service does make sense — just don’t fool yourself into thinking that you’ve decoupled your clients from your services.
That’s enough for now. I’ve likely raised more questions than I’ve answered here but this is definitely not my last word on this. I plan to provide more details in upcoming posts. Please fire away with the questions and feedback though so I can focus on the right areas.