REST as an Interface Strategy
Posted on August 16, 2016
Most software systems are created with the implicit assumption that the entire system is under the control of one entity, or at least that all entities participating within a system are acting towards a common goal and not at cross-purposes. Such an assumption cannot be safely made when the system runs openly on the Internet.
– Roy Fielding, Architectural Styles and the Design of Network-based Software Architectures (quoted in Leonard Richardson, Mike Amundsen, and Sam Ruby, RESTful Web APIs )
HL7 version 2 has a very powerful event model, and it has certainly stood the test of time. But it suffers from a major flaw: in order to design interfaces using HL7 version 2, it is necessary to know the event model ahead of time, and all participating systems have to agree on what the appropriate response to each trigger event should be. Of course, there are other issues: developing a common content model with agreed upon semantics, for example. But for now, we’ll focus exclusively on the dynamic model. In practice, this means HL7 messaging systems need to be centrally designed. Or, perhaps more to the point, system integration requires a lot of coordinated effort to be expended on each of the participating systems. This is precisely the problem Roy Fielding sought to address in his doctoral dissertation.
This may seem to be a theoretical issue, but developers and architechts generally approach interface development with a sense of trepidation, and whole industries have sprung up to help address problems encountered in interface development (the most obvious being the Enterprise Service Bus, or ESB). In recent years, a new approach to interface development called Representational State Transfer (REST), has become popular, and coninutes to gain momentum. It has even beeen incorporated as a key component of Fast Health Interoperability Resources or FHIR (pronounced “fire”).
So, what is REST, and how does it solve the problem of centralized application design? It is important gto understand at the outset that web services based on REST (often called RESTful services) are designed to operate much like a human interacting with the web, say reading a blog. If our hypothetical human user wanted to look for recent articles on a blog, she would start by opening up a web browser and pointing it to the main URL for that blog. Depending on how it is configured, the blog could return any of a number of things:
- A static page with a pointer to a list of articcles (known as the archives)
- A single article with a link to the next article at the end
- A list of short excerpts, perhaps with additional information such as the article length
- If there are more articles than can be displayed at once, there may be pointer (links) to the next, or perhaps previous, article
It is important that we know how to navigate the blog. Usually, this is not a problem because blogs follow one of a few well-known patterns, and the links are labelled to indicate their “meaning”, anyway.
Now, as I browse a blog, the server need not pay any attentiton to what I’m doing, or track client state in any way. This is another core principle of REST, and one that is often misunderstood. It is not the case that RESTful interfaces are stateless, or that they cannot be used to implement complex interactions. What is true is that the server does not track the client state. It is the job of the client to to navigate the application. The server, on the other hand, will tell the client what it can do at any particular time and how to do it (e.g., press this button to buy an item, or that one to cancel a purchase).
But now for a problem: how are applications to know the significance of the links or data elements returned in an HTTP response? If the client is an application, then it is no longer possible to rely on human intuition. The idea is that the server will return a map, and each turn on the map will be labeled in a standard way. If you think about it, hypermedia is precisely this kind of map. This is the key principle of Hypermedia as the Engine of State (or HATEOAS).
To make this more conrete, let’s consider The Atom Syndication Format (documented in Atom Syndication Format (RFC 4287)). Atom (much like its cousin, RSS) is often uused to produce versions of online newspapers, blogs, twitter feeds, or anything that can be treated as a series of articles, in a form that can be managed programmatically. It does this by using a special vocabulary that represents essential data elements (such as a summary), or linkingg elements (such as forward and back pointers).
Links to other documents use the XML <link> element, with the rel attribute identifying the type of link (e..g., “next”). Let’s look at an example taken directly from RFC 4287:
<entry> <title>Atom snapshot</title> <link rel="alternate" type="text/html" href="http://example.org/2005/04/02/atom"/> <link rel="enclosure" type="audio/mpeg" length="1337" href="http://example.org/audio/ph34r_my_podcast.mp3"/> <id>tag:example.org,2003:3.2397</id> <updated>2005-07-31T12:29:29Z</updated> <published>2003-12-13T08:29:29-04:00</published> ... </entry>
Notice that we have used the link tag to include altenate (audio) content, but other elements, such s <updated> and <published> are special to Atom.
In summary, REST allows state management to be decentralized, and it allows for parties to an interface to vary independently. Of course, that is only part of a solution. Other important pieces include controlled vocabularies and metadata.
Tagged: Atom, complexity, HTTP, hypermedia, interoperability, REST, web services