By now I’m sure everybody has at least heard of REpresentational State Transfer (REST). REST is an architectural style that was first properly described by Roy Fielding in his doctoral thesis. Since Fielding published his thesis in 2000 the term REST has become very popular among web developers. Mostly for the wrong reasons of course — REST and the derived term RESTful have morphed into marketing jargon for people who really mean "building a web site" when they say "implementing a RESTful architecture".
One of the things that has gone wrong in the area of REST-the-popular-interpretation is that people think that "doing REST" is the same thing as "using HTTP" (another thing is that they think that REST is something you can do). The reason of course is simple: most people use the term REST to mean building a web site. And you use HTTP for that. And in fact I thought it was not a wholly unreasonable position because one of the constraints of the REST architectural style is such that you really would not want to use anything but HTTP as a rule.
However, today, all of a sudden, I stumbled on ultimate proof that REST really is as independent from HTTP as Fielding claims: a piece of software that uses the REST architectural style but not HTTP.
REST: the short, short version…
Before we get to this marvelous, mythical piece of software let’s have a short recap of what REST entails. Real REST that is, not the bullshit about URI mappings, JSON and all the other nonsense that REST-the-marketing-buzzword has come to mean.
REST is not a codeword for building a web site. REST is also not something that you do. REST is an architectural style, which means that it is a general idea about what your application architecture should look like with some architectural choices already made for you. In particular the REST style is a general description of application architectures that make the following choices:
- client-server: The entire application uses a client-server architecture. This principally covers the interaction between the end user and the core application, but if the application consists of multiple components they use client-server communication as well.
- stateless: All inter-component communication (including the end-user client to the application service layer) uses stateless communication. This does not mean that a component cannot have state at all (like a database), but it does mean there is no concept like a running session or a session context. It also means that all external information needed to complete a request must be in the request.
- cache-able: At the discretion of a component in the system, a response to a request may be marked as cache-able. This means that the requesting component may cache the answer for later reuse.
- uniform interface: All components in the system use the same interface, no matter what their specific functionality. This interface therefore also becomes the communication protocol of the entire system, which simplifies building communication clients. System functionality is achieved by adding a distinct, addressable resource that offers the functionality and that is controlled using the shared communication protocol.
- layered: This constraint means that you cannot see through a component that you send a request to. As long as the client doesn’t control the processing of the server, the system remains scalable.
- code-on-demand: As an optional extra a server might send code to the client for local execution.
The architectural constraints above, in the sense of a preselected set of choices, are what makes REST. Anybody see any mention of JSON? No, neither do I…
So where does HTTP come in?
If you look at the architectural constraints again, you’ll see something else that isn’t mentioned (other than JSON): HTTP. REST does not imply HTTP. So why does everybody think it does? Just because Roy Fielding helped define HTTP? Because marketing guys want to sell web site work? No, it’s because of the uniform interface constraint. That constraint specifies that each component in the system is communicated with and controlled using a single protocol. Which means a single command set. In other words, no matter what the functionality of the component, it always answers to the same command set with the same possible parameters.
The uniform interface constraint is a very horrible idea. It is a complete contradiction of the principles of domain-driven design: having a uniform interface for all your components which is also your communication protocol means that you must encode domain concepts and operations in terms of the uniform interface instead of making them explicit in a domain language. It means your attention is diverted away from the application domain and domain model and even at the level of the most basic lesson we all learned in programming ("use explicit names for your identifiers") the uniform interface is a bad idea. Nobody in his right mind would ever use a uniform interface in a multi-component application they were designing.
In point of fact, there is only one situation in which you would want to employ a uniform interface in your application: in order to allow your application to become part of a larger, generally accessible system where participation brings you more users. Think plug-in architectures like the Eclipse platform… Or the World Wide Web, which runs on HTTP. So that’s why REST has become inextricably linked with HTTP: HTTP is the protocol for a network that is an ideal use case for the REST architectural style… and it’s practically the only example of a popular network that you would want to join in order to reach a large audience.
So it looks (for good reason) like REST and HTTP are congruent. Everybody who "does REST" uses HTTP and the HTTP-based WWW is practically the only interesting vehicle for real REST-style applications. And yet, and yet, today, in the wild, out of the blue, I came across a perfect example of that mythical beast: a REST-style application that doesn’t use HTTP as a uniform interface. So what was this application? The EZMLM mailing list manager.
EZMLM is, as said, a mailing list manager. That is, it manages a list of email addresses which are subscribed to a list (i.e. get a mail forwarded that is sent to a certain email address). In order to perform this management the EZMLM offers a number of command resources, each of which is triggered by the delivery of a message to that resource. Each command resource is individually addressable (using an email address as a universal resource identifier). My claim is that this program uses the REST architectural style. In order to prove this I must show that the architecture of EZMLM meets the constraints as explained above:
- client-server: EZMLM uses two components: a mail client (officially an SMTP user agent) and the EZMLM mail server. Like any SMTP-based email setup, this is a client-server application by definition.
- stateless: EZMLM has no concept of a session at all. Each request is somehow a mailing list management command which is atomic and no session is needed at all. The situation is somewhat deceptive because you might think that the mailing list itself is session state. However, this is not the case: EZMLM manages this list, that is true, but the list does not tie individual requests together into a session. Also, the list is not needed to make any request function correctly; all the information needed is in the mail message (usually that information consists of the contents of the FROM: header). This is true even for a command to the unsubscribe resource: the command still functions if the FROM: address is not on the list, it just cannot mutate the list (an error case is still correct processing).
Of course the mailing list does serve as server state, especially in case of a forward command (i.e. sending a mail to the list which is distributed to all list subscribers). However, the statelessness requirement doesn’t forbid server state. The important thing to realize is that the purpose of EZMLM is to manage the mailing list and that the mailing list does not function as session state information.
- cache-able: This requirement entails that the system might decide that some server responses may be cached. The client may then use its cache instead of talking to the server. This could be done using EZMLM, especially with the EZMLM response to the "help" command (the response is a list of command email addresses recognized by the EZMLM server). In practice EZMLM won’t do this, but the requirement is not that the system MUST have responses which it considers cacheable. Also, most user agents wouldn’t be able to handle caching of mails. But again, this is not a requirement.
- uniform interface: All one server components in the system use the SMTP protocol as uniform interface.
- layered: There is only one component in the system, so this requirement is trivially met. Still, if there were more components it is hard to see how their details would not be hidden behind the SMTP interface.
- code-on-demand: EZMLM does not use this optional constraint.
Again, the essential point here is to understand that there is a difference between managing a mailing list as function of the application and using that list as session state. Another point is the definition of a component. EZMLM uses other software (particularly qmail and its shell hooks) to deliver its functionality. However, EZMLM is buildable and deployable as a single package with all functionality and must be administered and maintained as a single package. Perhaps somewhat tentatively I will consider this enough to consider EZMLM a single component.
Simply put: miracle of miracles, there really is software that uses a REST style architecture but doesn’t use HTTP. So yes, against all expectation it is true and REST really is independent of HTTP!