Search code examples
apirestful-architecturemedia-type

HAL+JSON hypermedia type not a media type for REST?


Can the HAL+JSON hypermedia type be used in a way that creates a RESTful service?

From what I have read, the client of a RESTful API should not need to treat different resources with special cases. The media type should instead be used to describe what resources are expected to look like.

The HAL spec gives this example:

GET /orders

{
  ...
  "shippedToday": 20,
  ...
}

```

As a client of this sample HAL+JSON-serving API, I seem to need to know that an "order" has an attribute of shippedToday. That seems to go against the constraint that the client should not need to understand the representation's syntax.

This is not a critique of HAL. The question is to help my (and others') understanding of RESTful API design.


Solution

  • Can the HAL+JSON hypermedia type be used in a way that creates a RESTful service?

    Yes, definitely.

    The API should have a billboard URL, which in your case could be /.

    This is the entry point from which humans and ideally even machines can start to discover your API.

    According to the HAL specification a resources representation contains an optional property called "_links" which is described here:

    It is an object whose property names are link relation types (as defined by RFC5988) and values are either a Link Object or an array of Link Objects.

    So these links represent the hypermedia part of your API. The relations can be IANA-registered relations or you can use your own extension relations.

    Relations should not be ambiguous. Their names should be unique. That's why it is recommended to use URIs from your own domain as names for your own relations. These URIs identify a resource that represents the relation and contains an API documentation, a human or machine readable documentation of your relation.

    In your case this would be a relation that describes the state transition to the /orders resource. This should also include a description and explanation of the response and therefore document that e.g. the /orders resource represents a list of orders and has a property called "shippedToday" with a value of type number.

    Here is an example response for a GET / HTTP/1.1 request:

    HTTP/1.1 200 OK
    Content-Type: application/hal+json
    
    {
        "_links": {
            "self": { "href": "/" },
            "http://yourdomain.com/docs/rels/orders": { "href": "/orders" },
        }
    }
    

    Under http://yourdomain.com/docs/rels/orders there should be the API docs.