Sponsor: Do you build complex software systems? See how NServiceBus makes it easier to design, build, and manage software systems that use message queues to achieve loose coupling. Get started for free.
This post is in my Self Descriptive HTTP API in ASP.NET Core series. It demonstrates how to design an HTTP API like a regular HTML website. Bringing the concepts of links and actions to your API allows your clients to consume it with ease. If you’re new to this series, here are earlier posts to get up to speed:Hypermedia
You probably have already heard the term hypermedia before. Hypermedia and Hypertext are nothing new. They were both coined in the 60’s by Ted Nelson. You’ve definitely used hypermedia in the form of HTML. HTML has a great set of tags that represent hypermedia. When you are writing HTML and using<a>
<forms>
<img>
<link>
<script>
tags you are proving information to the client about other navigation or actions they can perform.
Your browser is nothing more then a hypermedia client that understands HTML. In the case of <a>
or <form>
the end user behind the browser ultimately decides if they are going to follow those links or submit the form. You generally hit a a website either by navigating from another site, or manually enter the URI in your browsers address bar. You then navigate the site via links and forms. I generally don’t see people typing in every URI in there browser address bar 🙂
Googlebot (web crawler) is another great example of a hypermedia client that understands HTML. It follows <a>
tags through your site to crawl all the exposed pages. Googlebot doesn’t know how to craw a random URI on your site unless you tell it.
It’s not magic. It’s about returning a media type (content-type) and payload the client can understand.
APIs
What I find really interesting is even with how successful HTML is the popularity of using hypermedia in our HTTP API’s seems really low. It’s not because of lack of media types. HAL (Hypertext Application Language) was the first media type I discovered when starting thinking about the idea of linking one URI to another in my HTTP API. I was late to the party since these ideas started coming to me several years after HAL was created in 2011. Since then have been other media types that have gained some traction:Actions
Following CQRS, I expose commands and queries and URIs. Some media types like HAL don’t really give me the ability to specify how to perform various actions (commands) with payloads a user can invoke in the system. However, a media type like Siren does. The general idea can really be related to an HTML<form>
Here is a basic HTML form. If you were creating an client that understood HTML you would be able to easily create a HTTP request to perform the action.
The above form describes an action. If we wanted to create an HTTP request to submit this action, we have all the information in the form to build the request.
- The URI is by action=”/books/add”
- The HTTP method used whith the method=”post”
- The body of our request is defined by the <input> and <select> elements
- The select <option>’s define valid valid for the price
Self Descriptive
By using a media type like Siren we can start to develop HTTP APIs that are self descriptive. It’s a combination of the content type and the message body that makes our API self descriptive. You cannot just return arbitrary JSON and expect your clients to understand how to use it. They must understand what the content is.@codeopinion @joe_mighty Exactly. The entire message should be self-description. It’s a HTTP message and should use HTTP mechanisms to identify the content.
— Darrel Miller (@darrel_miller) April 20, 2017
I love the concept of hypermedia. And it’s actually quite easy to add links to your responses, so that the client can follow them. But I haven’t yet found an easy way of consuming a hypermedia API from a UI. I’ve managed to cobble together something that sort of works, but it shouldn’t be that difficult.
IMO, the Hypermedia API is the UI. One resource, two representations, one for a human, one for a machine.
I think using Swagger to document your API is the cleaner approach check http://swagger.io/
I don’t believe Hypermedia and Swagger/OpenAPI can even be compared. They have similarities in regards to defining endpoints but that’s where I would draw the line. With hypermedia, the media type and payload define how a client can make subsequent requests to my API. The workflow is defined by the server and through the payload it media type and payload it returns. URIs become irrelevant to the client.