2014-07-30

hal+json is the way to go for representing REST resources

If you are implementing REST APIs, and are thinking about using application/json as your content type, please consider application/hal+json. It allows you to represent link relations and embedded resources in a standardized manner.

The content type offers three things:

  1. Semantic link relations using the _link key. The self link is a good example.
  2. Embedded resources using the _embedded key, which are a subset of the link relations
  3. Properties with arbitrary keys

As an example, you might have a programmable power strip with three sockets. The strip itself can be modeled as a resource. It will have three optionally embedded resources with the link relation sockets. These resources themselves will have a link relation called toggle. Doing e.g. a POST on this resource will allow you to toggle it. The lovely thing here is that the API will give you the correct URL to turn on or off the socket. An example request and response:

GET http://foo.com/powerstrip/1
Accept: application/hal+json

{
    "_links" : {
 "self" : { "href" : "http://somedomain/powerstrip/1" },
 "sockets" : [
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 1" },
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 2" },
     { "href" : "http://somedomain/powerstrip/1/sockets/1", "name" : "Socket 3" }
 ]
    },
    "_embedded" : {
 "sockets" : [
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/1" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/1/off" }
  }
  "state" : "on"
     },
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/2" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/2/on" }
  }
  "state" : "off"
     },
     { 
  "_links" : {
      "self" : { "href" : "http://somedomain/powerstrip/1/sockets/3" },
      "toggle" : { "href" : "http://somedomain/powerstrip/1/sockets/3/on" }
  }
  "state" : "off"
     }
 ]
    },
    "numberOfSockets" : 3,
    "voltage" : 230
}

The content type is described in an RFC draft, and is well on its way to become a standard. Make sure to also read the associated web linking RFC.

Amazon is already using this content type in its AppStream API.

The strength of using link relations and a content type such as HAL is that you can actually document your link relations, which are a fundamental part of your API. You should actively design the link relations and make them meaningful.

For resources, I recommend that you document the following aspects:

  1. Expected link relations and their embeddedness
  2. Attributes of the resource
  3. Example method calls for all allowed methods (GET, POST, ...) with example responses 

For link relations you should document these aspects:

  1. Synopsis what the link relation means or represents, and which resource is to be expected
  2. Allowed methods with optional templated arguments
I place the example method calls with the resource documentation, since they might be redundant if specified with the link relations. But you should link to the resource documentation from the associated link relation documentation.

No comments:

Post a Comment