What is REST and why do we use it? Part 3: Hypermedia Navigation

If you spend any time reading about REST on the interwebs, you’re probably seen the ugliest acronym outside of the government: HATEOAS. That charming tongue-twister stands for hypermedia as the engine of application statement. If you’re anything like me, that raises two questions: (1) WTF does that even mean? (2) HTTP is stateless, so why should I care?

Kindly allow me to explain what HATEOAS means and why you should care.

The fundamental operations of any API are CRUD. “Retrieve” is the most basic, so I will focus on that operation, but these principles can be easily extended to the other CRUD operations and to more sophisticated API calls, too.

Let’s imagine that we have a REST interface for an animal hospital. We can retrieve information for a specific pet with GET /api/animal/{id}, and the server will give us some data in a nice JSON object. HATEOAS expands the response to include URLs for endpoints that are relevant to the pet. Moreover, the URLs are documented in such a way that the client can understand what each one does.

Continuing the example, let’s imagine that the animal hospital’s API allows us to retrieve the pet’s medical history, her current medications, and her owner. We can also update her information. With HATEOAS, the response to our GET request will include URLs for each of these actions (along with the appropriate HTTP verbs). The response will also include documentation for each URL so that a client (whether it’s a web app, a mobile app, or another service in the cloud) can understand what each URL is for.

If you’re having trouble visualizing how this response might look, consider the different between the HTML of this webpage and the view you are currently seeing. The raw HTML includes metadata that tells the browser how to display the text of the article. Similarly, the raw JSON of a HATEOAS response will include metadata for each of these related URLs.

So that’s what HATEOAS is, but you’re still wondering why you should care. After all, HTTP is a stateless protocol.

Yes, it is.

But your application is not stateless. Consider the humble example of a shopping cart. The list and quantity of items in your cart is maintained in your browser1 or on the server. When you view a product with a hypermedia2 API, the server response includes a URL for adding the product to your cart. The client doesn’t need to know this information beforehand, not does it need to figure it out for itself. It’s just right there. Similarly, retrieving data for the cart itself will include URLs for updating product quantities, removing items from the cart, and so on.

This is cool!

As the API developer, you don’t have to document specific endpoints. With hypermedia, you just have to document the URL descriptors. The descriptors are drawn from a small vocabulary, so you don’t have to invent some complex semantic parsing engine or something. Documenting the descriptors should be no more complex than documenting endpoints.

This solves a very real problem: even the best API design will evolve and change over time. It’s inevitable. With a hypermedia interface, the clients can adjust themselves without any intervention from a code monkey!

In addition, the URL descriptors are likely to change even less than the URLs themselves. Consider our animal hospital from earlier. The URL might change to /api/pet/{id} or /api/patient/{id}, but the client will still want to access her history, medications, and so on.

One of the criticisms of hypermedia is that developers read documentation, so the interface doesn’t need to be self-documenting. This is absurd on its face. Developers reading documentation? Yeah, right. Developers both inside and outside your organization are going to learn your API by hacking on it with curl or Postman. You should make their lives easier, and make your interface self-documenting. Happy developers build and maintain better client apps, driving overall adoption of your service.

Another criticism is that there is no magical client that will understand the endpoint descriptors out of the box, so there’s no point in using hypermedia. That’s true. There’s no universal client. So what? I didn’t realize that was something we were aiming for.

You can still build a client for my API that understands my descriptors. You’ll have to build a different client to understand Facebook’s API and their descriptors. That will still get you all of the advantages of hypermedia that I discussed above, even if you have to build different clients for different APIs. Even without a magical “smart client,” hypermedia is still more useful than plain old, non-hypermedia server responses.

It’s not a panacea, but it’s an improvement over the status quo–one that will pay off in both the short term and the long term.

  1. If the app was built in 1997. [return]
  2. “HATEOAS” is only slightly less fun to type than to say, so I’m just going to call it hypermedia from here on out. [return]