- Live Demo
- Contact Us
Stop Talking About Hypermedia and REST - Start Building Adaptable APIs
This post originally appeared on the Strategy Services blog.
I had a brief moment of enlightenment at last week’s API Craft conference in Detroit while leading a session I titled “How Do We Help Developers Implement the APIs of Tomorrow (or Today)?” Many of the responses coming back from the crowd took some form of “use hypermedia.” Listening to these and seeking answers as to how to best communicate this to developers, I felt the need to stop the conversation to ask what I thought should be a simple question.
“What is hypermedia?”
Many of us had spent the previous day listening to a panel of API experts talk about hypermedia and how the various response formats they created (JSON-LD, Hydra, Siren, HAL, etc.) addressed and supported it. In fact, I could see some of those same experts in the crowd standing before me, all of them searching for a way to express the right way to respond.
“Like, in one sentence?” piped one brave soul. “I don’t think you can do it in one sentence.”
Another answered by describing it as “an API that can be documented without writing one single absolute URL or relative URL path,” which speaks to hypermedia’s apparent ability to self-document, but does little to explain exactly how that’s implemented.
This should have been an easy question to answer, but it turns out even the experts grope for a description when pressed. For my part, I consider an API to support hypermedia when it does the following:
- Each resource points to related resources and available actions using the method native to its protocol (i.e. using URIs over HTTP).
- Each resource clearly defines its media type so a client knows what it’s parsing (i.e. by providing a MIME type in the “Content-Type” response header) and responds appropriately when requested to return a specific media type (i.e. when a client lists it specifically in the “Accepts” request header).
- Each resource points to a machine-readable description of how to parse its media type. (i.e. through one of the many emerging API descriptor languages, such as I/O Docs, Swagger, RAML and Blueprint).
Few protocols outside of HTTP provide for this full set of actions, which is appropriate since the “H” in “HTTP” stands for “Hypertext”. In other words, it’s a protocol built specifically to deal with hypermedia. This becomes obvious once you realize that the most robust hypermedia client in the world today is the very browser you’re using to read this post.
To describe how a hypermedia API should operate, Brian Sletten suggested at last year’s REST Fest conference that you should ask yourself, “What Would the Browser Do?” Out of the box, most web browsers can handle the most common media types—the text-only text/html, text/xml and text/json media types, of course, but also image/jpeg, image/png and image/gif, which each define graphical image formats expressed in binary requiring special parsing to display. When greeted by a media type it doesn’t recognize—application/x-shockwave-flash, for example, which is used when an Adobe Flash object is being sent—most browsers have a facility to search for and install a plugin that can handle that media type inline with the rest of what it’s displaying.
This makes the browser highly adaptable as new media types representing different technologies arise. So long as a plug-in has been created for the browser and the browser can find it, it will adjust. This adaptability is what has made the web a dominant standard over the last 20 years. It’s not the browsers, but their ability to use the hypermedia facilities used by servers to be able to adjust as new data types become available.
I’ve attempted to express this in the NARWHL API design framework I developed earlier this year. NARWHL arose from my observation that development teams creating APIs were getting too caught up in the implementation details—what should the URIs look like? Should everything be expressed as links and traversed from the root, or should they be atomic? And what response format should we use? What if the format we choose doesn’t fit our model?
NARWHL is intended to get past these details, providing a clear path forward on how to design an API that can change as business needs change and standards start to settle without disrupting client applications any more than necessary. While it accomplishes this by adhering to hypermedia constraints, the ultimate goal is to build adaptable APIs. Hypermedia is just the means, adaptability is the ends.
Your URI layouts, response formats and descriptor language choice are implementation details - on that all the experts at API Craft could agree. The number of different ways you can create a RESTful API is many, varied and growing and shows no signs of settling down any time soon. If you are building an API intended to be used today, but are worried about whether it will still work tomorrow, allow me to calm your fears. Build the API today that best suits your needs and fits your model. Choose a descriptor language that best allows you to describe it. Make sure every response includes the Content-Type that represents it and make sure there’s a common way for a client to request the descriptor definition for that Content-Type (NARWHL recommends using a “Link” header in the response with the “rel” set to “service”, but I will soon be adding another recommendation that can complement or potentially replace that). And make sure you express every possible transition/action available to a resource as well as its related resources in the form of links, including the relationship (expressed using the “rel” parameter) and the method (i.e. “GET”, “PUT”, “POST” and “DELETE”). Encourage your client developers to trust your links, pay attention to your Content-Types, make use of the Accepts header and use your descriptor documents to parse your responses in real time.
Following these simple rules today will ensure your API adapts to the needs of tomorrow. Free yourself from worrying too much about the implementation details and instead focus on modeling your API to provide flexible solutions that address the challenges your developer customers are solving. If you want to build a successful API, build an adaptable API.