Common Hypermedia Types

In the design of APIs you are quite likely to end up in a quagmire on how to represent your data. Now in some way we have already looked at the problem in the past http://206.189.161.181/2015/05/dry-up-your-api-with-microformats/. However microformats can only take you so far, you may need to design a full on API service and that is where hypermedia comes into play.

There are an innumerable number of hypermedia types so I will just stick to the main ones.

HTML (Hyper Text Markup Language)

This is by far the most familiar media type of all.

It is characterized by use of tags to differentiate document content.

An example of a representation in HTML would be:

    <ul>
      <li>
        <a href="/list/1" rel="item" class="item">
          <span class="identifier">1</span>
        </a>
        <span class="name">First item in the list</span>
        <span class="scheduledTime">2014-12-01</span>
        <span class="status">pending</span>
      </li>
      <li>
        <a href="/list/2" rel="item" class="item">
          <span class="identifier">2</span>
        </a>
        <span class="name">Second item in the list</span>
        <span class="scheduledTime">2014-12-01</span>
        <span class="status">pending</span>
      </li>
      <li>
        <a href="/list/3" rel="item" class="item">
          <span class="identifier">3</span>
        </a>
        <span class="name">Third item in the list</span>
        <span class="scheduledTime">2014-12-01</span>
        <span class="status">complete</span>
      </li>
    </ul>

You can learn more about HTML from http://www.w3.org/TR/html5/

JSON-API

This hypermedia type uses JSON (JavaScript Object Notation) to define content in your representation. It has been around for a while and is currently stable at v1 at the time of this writing.

{
  "data": {
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!",
      "body": "The shortest article. Ever.",
      "created": 1432306588,
      "updated": 1432306589
    },
    "relationships": {
      "author": {
        "data": {"id": 42, "type": "people"}
      }
    }
  },
  "included": [
    {
      "type": "people",
      "id": 42,
      "attributes": {
        "name": "John",
        "age": 80,
        "gender": "male"
      }
    }
  ]
}

You can read more on this media type from here http://jsonapi.org/

Collection+JSON

Another media type based on JSON.

Collection-JSON can be used to do much more than just describe data. It provides query templates that instruct the client on how to properly format requests.

It provides specifications for the entire conversation between server and client.

It borrows a lot of its semantics from the Atom format

*** REQUEST ***
GET /my-collection/1 HTTP/1.1
Host: www.example.org
Accept: application/vnd.collection+json

*** RESPONSE ***
200 OK HTTP/1.1
Content-Type: application/vnd.collection+json
Content-Length: xxx

{ "collection" : { "href" : "...", "items" : [ { "href" : "...", "data" : [...] } } }
// query template sample
{
  "queries" :
  [
    {
      "href" : "http://example.org/search",
      "rel" : "search",
      "prompt" : "Enter search string",
      "data" :
      [
        {"name" : "search", "value" : ""}
      ]
    }
  ]
}

You can read more about this media type here http://amundsen.com/media-types/collection/format/

Siren

Like the above two, this media type is also based on JSON.

Siren emphasizes on your data structures (they call them entities) and the relationships between them.

The media type is however not yet stable and still in active development.

{
  "class": [ "order" ],
  "properties": { 
      "orderNumber": 42, 
      "itemCount": 3,
      "status": "pending"
  },
  "entities": [
    { 
      "class": [ "items", "collection" ], 
      "rel": [ "http://x.io/rels/order-items" ], 
      "href": "http://api.x.io/orders/42/items"
    },
    {
      "class": [ "info", "customer" ],
      "rel": [ "http://x.io/rels/customer" ], 
      "properties": { 
        "customerId": "pj123",
        "name": "Peter Joseph"
      },
      "links": [
        { "rel": [ "self" ], "href": "http://api.x.io/customers/pj123" }
      ]
    }
  ],
  "actions": [
    {
      "name": "add-item",
      "title": "Add Item",
      "method": "POST",
      "href": "http://api.x.io/orders/42/items",
      "type": "application/x-www-form-urlencoded",
      "fields": [
        { "name": "orderNumber", "type": "hidden", "value": "42" },
        { "name": "productCode", "type": "text" },
        { "name": "quantity", "type": "number" }
      ]
    }
  ],
  "links": [
    { "rel": [ "self" ], "href": "http://api.x.io/orders/42" },
    { "rel": [ "previous" ], "href": "http://api.x.io/orders/41" },
    { "rel": [ "next" ], "href": "http://api.x.io/orders/43" }
  ]
}

You can contribute and learn more about this particular media type from their official repo https://github.com/kevinswiber/siren.

UBER (Uniform Basis for Exchanging Representations)

Of all the representations above, this is the most comprehensive.

UBER can be represented in both XML and JSON. It is designed to enable the developer represent transitions in their APIs.

{
  "uber" :
  {
    "version" : "1.0",
    "data" :
    [
      {
        "rel" : ["self"],
        "url" : "http://example.org/"
      },
      {
        "name" : "list",
        "label" : "ToDo List",
        "rel" : ["collection"],
        "url" : "http://example.org/list/"
      },
      {
        "name" : "search",
        "label" : "Search",
        "rel" : ["search","collection"],
        "url" : "http://example.org/search{?title}",
        "templated" : "true"
      },
      {
        "name" : "todo",
        "rel" : ["item","http://example.org/rels/todo"],
        "url" : "http://example.org/list/1",
        "data" :
        [
          {"name" : "title", "label" : "Title", "value" : "Clean house"},
          {"name" : "dueDate", "label" : "Date Due", "value" : "2014-05-01"}
        ]
      },
      {
        "name" : "todo",
        "rel" : ["item","http://example.org/rels/todo"],
        "url" : "http://example.org/list/2",
        "data" :
        [
          {"name" : "title", "label" : "Title", "value" : "Paint the fence"},
          {"name" : "dueDate", "label" : "Date Due", "value" : "2014-06-01"}
        ]
      }
    ]
  }
}
<uber version="1.0">
  <data rel="self" url="http://example.org/" />
  <data name="list" label="ToDo List" rel="collection" url="http://example.org/list/"/>
  <data name="search" label="Search" rel="search collection" url="http://example.org/search{?title}" templated="true" />
  <data name="todo" rel="item http://example.org/rels/todo" url="http://example.org/list/1">
    <data name="title" label="Title">Clean House</data>
    <data name="dueDate" label="Date Due">2014-05-01</data>
  </data>
  <data name="todo" rel="item http://example.org/rels/todo" url="http://example.org/list/2">
    <data name="title" label="Title">Paint the fence</data>
    <data name="dueDate" label="Date Due">2014-06-01</data>
  </data>
</uber>

To read more on this check out https://rawgit.com/uber-hypermedia/specification/master/uber-hypermedia.html

This are obviously not the only formats. Checkout IANA for comprehensive list of published formats

Thats it folks, you have even more interesting formats please comment below.

Don’t forget to Signup for our newsletter

Facebooktwittergoogle_plusredditpinterestlinkedinmail

Published by

jchencha

Software Project Manager