A hypermedia API is simply an APIs that contains links in the responses. In this tutorial, you’ll learn what such an API looks like and why you might want to create one. Ismael Celis over at Thoughtbot will take you thru building a generic Ruby client written according to Hypermedia design patterns.
Before we get started, it’s necessary to say what we mean by ‘link’ here. A link can be not only a regular HTTP address but also a minimum piece of information to instruct the client on how to work with referenced resources. So, for example:
An HTML form like this could be a link. It tells the client to send a put request according to the above schema.
To get a better understanding of how hypermedia APIs look and work, we’ll start with a simple shopping cart API example. The API gives us information about orders with GET requests and allows us to place them with PUT requests. With a standard REST API, you have to concatenate URL paths to get information about particular orders, for example. This can be tedious so you might want to create a standard Ruby API client library to hide these details under the hood.
We’ll now redo this example with hypermedia. This will involve encoding state transitions (i.e. actions) as links in API responses. So, for example, the response for a request like this: ‘GET /orders/123’, will be:
Unlike a standard API response, this tells you more about the current state of the order and what you can do with it.
Writing a Generic Hypermedia API Client
When the API returns such responses, you’re in a position to write a client that can learn what actions you can perform with the API. For this, you’ll need first to implement a class that wraps API resources and exposes its attributes and links. We’ll call this initial class ‘Entity’.
For links, we’ll create a Link class that’ll manage the HTTP request and return the response. You can then instantiate that link class by passing the link data and the HTTP client instance. Links can then be run like any call to a class method. For example, you can place an order like this:
Under the hood, the link wrapper class delegates the HTTP request handling to the HTTP client. The class is initialized with link data and the client. The run method will run the relevant request with the HTTP client and the response will be returned in a new Entity.
Figuring Out Which Resources Support Which Links
We’d like to know what links resources offer. We can add some syntactic sugar to the Entity class to make it easier to figure out what are the supported links of any resource.
The client can then write code to decide what to do based on what capabilities the resource offers. So for example, you could have the following conditional logic:
The API Root
With a hypermedia API, like with a website, the only address the client needs to know is the root address to access any resource. The root resource will return all the other resources. We just need to wrap the link and entity classes in an agent class that can be initialized with the root address to finish off.
Once you’ve initialized your API client. You simply need to follow the root and use the names of the links by name to do things like create orders.
The advantage of the hypermedia approach is that you can build entire workflows into the API design to make things easy for your client. For example, you can create a workflow for pagination in cases where the resource produces lists of things. You simply extend the Entity class to implement an Enumerable interface like you do in a language like Java. The client can then use the interface to enumerate a list of items that is spread over several pages like so: