This is part one in a series about hypermedia and REST. If you like this and want to read more, check out the full series.
When Kent Beck describes how he developed Extreme Programming, he talks not about fixing the things that don't work, but rather turning the dial to 101 on things do work. For example, we know that code reviews can help find bugs and improve code. We also know that the more often we do code reviews the better they work. If we turn the frequency of code reviews up to the max, we have Pair Programming. There is someone reviewing your code in realtime as you code. Woody Zuil calls this concept, "turning up the good"2.
REST the Good Parts
So, what if we applied this concept of turning up the good to REST APIs? In order to answer this question, we need to identify the good parts we want to turn up.
One of the main benefits of using REST to build APIs is that we can use use existing web standards like URI and HTTP. We don't have to reinvent a way to identify things (URI) or how to pass messages between the client and server (HTTP). When everyone follows these standards, we have a uniform interface that allows us to understand what an API does by looking at its URIs and the HTTP methods it supports. We don't have to learn a new vocabulary every time we work with a new API.
Reality Check
That sounds great in theory, but in real life things get messy. Despite everyone working from the same standard, there are nearly as many interpretations of those standards and opinions on "best practices" as there are APIs. This throws a wrench into the promise of being able to understand what any API does at a glance. It also means that every API needs its own client that understands its particular flavor of HTTP.
The other problem with using HTTP as a uniform interface is that not everything fits in a neat little box. If your API needs to do something other than basic CRUD operations, you have to rely heavily on documentation to express what your API does.
Uniform Interface
Let's put all that aside for now and come back to it later. In theory, a uniform interface for APIs is a good idea. So, let's turn that idea up and see what effect it has on the problems that were identified. The big win for having a uniform interface is that it allows us to automate a lot of our interactions with APIs without having to know about the complicated inner workings.
There are many HTTP clients out there that do some of this automation. For example, in JavaScript, I can use the fetch
HTTP client to do something like this.
fetch('http://example.com/foo').then((response) => {
if (response.ok) {
// happy path
} else {
// sad path
}
});
I didn't need to know how to construct an HTTP request or how to parse the response. I didn't even need to know that a 200 OK
status means the request was successful. The HTTP client abstracts those details. Something like this can potentially do all kinds of useful things for us automatically, such as caching or retrying failed requests. That's a pretty big win that we take for granted.
Turn up the Good
That's the norm today, but what else can we automate to make our work easier? Since REST is an architectural style that describes the web, we can look to the web for inspiration. With the web, we have web browsers instead of HTTP clients. Billions of people use web browsers every day without having to know anything about URI, HTTP, or HTML. At the same time, the web's uniform interface is flexible enough to support almost any application we can think of.
One of the things the browser automates is parsing HTML and creating a graphical display including content, links, and forms. HTML is part of the uniform interface of the web, and processing it is something that can be automated. A REST API client doesn't need to do anything with graphics, but it can benefit from links and forms just like the web does.
Links and forms are collectively known as hypermedia, and are a uniform interface for connecting graphs of related resources and defining workflows. We can use hypermedia with APIs to automate these things the same way a browser does. The missing piece is a mediatype like HTML that supports hypermedia, but is optimized for data transmission rather than graphical display. The most popular data format for REST APIs today is JSON, but because JSON doesn't support hypermedia, we can't make clients on the level of web browsers.
Many have taken a stab at defining a hypermedia type for data, but there is no clear winner. Some of the more popular choices are JSON Hyper-Schema3, Hydra4, HAL5, and Siren6. Despite all these options, it has not yet been a popular idea to automate the processing of these media types with REST API browsers. The big win with uniform interfaces is automation, so let's turn up the good and start getting the benefit of hypermedia without burdening API consumers with having to learn the details of your chosen hypermedia media type.
Where does this get us?
The web is an example of a successful uniform interface capable of describing just about any application that is runnable on a generic client. By taking lessons from that uniform interface, we should be able to create an API Browser that you can use to interact with any API without needing to know anything about the complicated standards that make up the web.
The problem of the HTTP methods not being descriptive enough for every application goes away when a self-descriptive, hypermedia-enabled media type is part of your uniform interface. Not only that, but you can throw away most of your API documentation because the API is self-describing just like a web application.
The problem of different APIs having different interpretations of the standards goes away when developers are targeting API Browsers. If your API doesn't follow the standards, then it won't work with API Browsers. No one wants that. Working with a generic API Browser is not only preferred by API consumers, it's preferred by API developers because they don't want to have to write and maintain their own client.
What's next
This is the first in a series of posts about hypermedia. I glossed over a lot of the details this time. In the following posts, I'll get into more details about REST and hypermedia and how we can make this vision a reality. In the next post we will do a deep dive on hypermedia.
Check out Part 2: Decoupling the Client and Server with Hypermedia.