This opinion has been stewing for a couple of years now, but following an excellent conversation I had with Ted Young the other evening at the API Craft San Francisco event, I think it is time to have more discussion around this subject.
A little bit of history
I have been a big supporter of the HAL media type ever since Mike Kelly showed me his first sample on the freenode #REST IRC channel. I actively pushed for the use of HAL within several teams at Microsoft and a number of other large corporations. I saw HAL as an opportunity to introduce people to hypermedia using a simple, flexible, standardized format. HAL has its flaws, but it served my purpose.
Since HAL was introduced, a number of other hypermedia types have been created, including Collection+JSON, Siren, JSON-LD, JsonAPI, Mason, UBER, OData and probably a few others that I have forgotten.
I think it is excellent that there is experimentation going on in this area. Much of this work can be used as the basis for future media type designs. The more people who have experience creating media types the better. However, there is a trend emerging where we are repeatedly creating general purpose hypermedia types that attempt to provide a single solution for all the resources in a API.
What's the problem?
Developers who wish to build a hypermedia API are now required to make a decision up front on whether they want to use HAL, or Siren, or Mason, or JSON-LD, or OData, or UBER. All these designs are only incrementally different than each other and simply reflect the preferences and priorities of their authors.
The fragmentation of our already fairly small community of developers who are using hypermedia formats is really not helping us advance the adoption of hypermedia. Additionally, by trying to build hypermedia types that are sufficiently generic to support a wide range of use-cases, we have been forced to introduce secondary mechanisms to convey application semantics. Once a developer has chosen a hypermedia format, they must now choose a profile format, or a schema language, or create extension link relations in order to communicate the remainder of the semantics that the general purpose hypermedia formats do not support.
I intentionally left Collection+JSON out of the list of competing media types because I see C+J as different, as it was designed to represent a simple lists of things. This a very focused goal and yet one that almost every application has the need for.
So what does work?
I realize that this example is going to turn off many people, but there is an elephant in the room that we just can't continue to ignore. The human web is built around a fairly small set of media types that have narrowly focused goals.
text/html
provides read-only textual content to be presented to an end user.application/x-www-form-urlencoded
provides a way of transmitting user input to an origin server.text/css
provides hints to the user-agent on how to render the content of the HTML document.image/(png|jpeg|gif)
provides bitmap based imagesimage/svg
provides vector based imagesapplication/javascript
provides source code for client side scripts
It is the combination of these narrowly focused media types that enable web applications to produce a huge variety of user experiences.
The UNIX philosophy
In my opinion the best media types are the ones that are designed to solve a single problem, solve it well and then allow the combination of those media types. This allows the media type to remain fairly simple. Simple to create, simple to parse and simple to replace if a better format comes along. It is also easier to support multiple similar formats. The web only supports one text/html
format, but it supports several image formats.
Examples of potential media types
During my years of building hypermedia based systems, I have run into many situations that would have benefited from having specialized media types. Here are some examples:
- Discovery document : An entry point document that allows a client to discover other resources that exist within a system. e.g
json-home
- List of things : A tabular list of pieces of data. e.g.
Collection+Json
,text/csv
- Data entry form : A representation of a set of data elements that have types, constraints, validation rules, intended for capturing information from the user. e.g. HTML forms are a very primitive example
- Captured event stream : A sequence of events captured by a client application potentially used for replaying on some remote system. e.g.
ActivityStreams
,Json-patch
- Error document : document used for reporting errors resulting from a HTTP Request. e.g.
http-problem
,vnd.error+(xml|json)
- Operation Status document : Document which describes the current status of a long running operation.
application/status+(xml|json)
- Banded Report document : Representation of the set of data used by report writing tools to generate printed reports
- Query description : Query language that selects and filters a subset of data e.g.
application/sql
,application/opensearchdescription+xml
- Datapoints : for driving dashboard widgets and graphs
- Security permissions management : tasks, claims, users
- Patch format : Apply a delta set of updates to a target resource
Json-patch
Call to action
I'd like to see those developers who do have experience building hypermedia types working on these kinds of focused media types instead of creating competing, one-size-fits-all formats.
I'd like to see widget and component developers building native support for consuming these specialized media types.
I'd like to see more application developers identifying opportunities for creating these specialized media types.
I'd like to see API Commons filled with a wide variety of media type specifications that I can pick and choose as building blocks for building my API.
I want to have a future where I can expose my data in a standardized format and then simply connect hypermedia enabled client components that will consume those formats. Now that would improve productivity.
That's my opinion, I'd love to hear yours.
Image Credit: Vanilla Ice cream https://flic.kr/p/9JyfVG
Image Credit: Sundae https://flic.kr/p/3aK9TU
Image Credit: Toppings https://flic.kr/p/fuY7GZ