Pragmatism in the real world

RESTful APIs and media-types

Evert Pot recently posted REST is in the eye of the beholder. Go ahead and read it; it’s good!

It discusses the fact that most APIs that are self-described as RESTful are not hypermedia driven and hence are not actually RESTful as originally defined by Roy Fielding. Evert goes on to state that therefore the term “REST API” has changed to mean an HTTP API that isn’t hypermedia-driven.

I think that what the world currently calls RESTful APIs fall short in more ways than just not serving Hypermedia links.

Media-types provide value

The majority of HTTP APIs out there do not reap the benefits of using media types correctly either. The majority seem to use application/json and call it done. The client gets absolutely no information about how to read the data, other than they’ll need a JSON decoder… This is like having an HTML file and using a `.txt` file extension. It’s correct in the sense that the the file is plain text, but absolutely useless for interpreting the file to render a web page.

Media types allow an API to inform the client how to interpret the data in the payload. This is arguably much harder than adding hypermedia to an API. The correct media types enforces the structure of the payload and also what the payload data means.

This is why most APIs just use application/json. If you’re lucky, there’s some documentation somewhere that explains things. Half the time, we seem to expect client developers to read the JSON and interpret it based on experience.

The best example of where this works well is the media type “text/html“. Given a payload in this media type, a web browser can render the information in the way that the web developer (api server) automatically. This is because every server that sends a document with a text/html payload sends the same tags for the same meaning.

We can do this in the API world too, but it requires thinking about and is harder, so it doesn’t happen…

There are three uses of media-types that I see in the world:

  • Plain: application/json (or application/xml
  • Vendor specific: e.g. application/vnd.github.v3+json
  • Standard: e.g. HAL, Collection+JSON or JSON-API, Siren, etc.

There is no practical difference between an API that uses a Plain media type and one that uses a Vendor specific one. As a client developer, you have no clue how to interact with the API or deal with its payload. To integrate with this API you need Google and hope you find enough documentation.

An API that uses what I’ve called standard media types give a client developer a leg-up. There’s an official specification on how the data in the payload is organised. The standard is documented! This makes a difference.

You always need human-readable documentation to integrate with an API. A standard media type, implemented properly, makes it much easier. For starters you don’t need to write as much as the standard has taken care of a good proportion of the boring bits. Something like HAL’s curies provides an unambiguous way for the developer to find the right documentation for the endpoint they are dealing with.

JSON-API’s pagination and filtering rules mean that I can write code once that will work with every API that uses JSON-API that I have to integrate with. This is powerful!

We can even go further with structured data as defined at schema.org to provide standardised field names for our data, but that’s a topic for another day.

Evert is correct

I’ve used Evert’s post to point out that when we talk about Hypermedia in a RESTful API, we mean more than simply putting in a few links in the payload.

Going back to Evert’s article, he is correct; the term “REST API” is pretty much meaningless and at best simply means “An API that works over HTTP with some awareness of what an HTTP method is”. The current term for an API that meets the constraints of REST is “Hypermedia API“.

I think that providing an API with hypermedia & a well-documented media-type is beneficial for every API. APIs last longer than you believe and it’s a competitive advantage if a developer can integrate with yours easier and faster than with your competitor’s.