Skip to content

Media Types

Except where noted on each resource's specification, all HTTP responses use the application/json+hal media type.

This is (or should be) supported by any HTTP client as regular JSON but allows higher level clients to be built using the hypermedia features of the HAL media type.

A brief summary of HAL

HAL can be interpreted as plain JSON but reserves the following two field names: * _links, containing the links to resources associated with the current resource; * _embedded, which embeds data from links.

An example response using HAL:

{
    "name": "John Doe",
    "_links": {
        "self": { "href": "https://example.com/john" },
        "status": { "href": "https://example.com/john/status" },
        "https://openpublishing.com/authored-books": { "href": "https://example.com/book?author=john" }
    }
}

The _links field is key-value mapping where each key is the name of the relationship type and the value is either a link object or an array of link objects (this is allowed by the HAL specification).

A common case is returning several results for a query:

{
    "_links": {
        "self": { "href": "https://example.com/book" },
        "item": [
            {
                "href": "https://example.com/book/1",
                "name": "Crime and Punishment"
            },
            {
                "href": "https://example.com/book/2",
                "name": "War and Peace"
            },
            {
                "href": "https://example.com/book/3",
                "name": "Pride and Prejudice"
            }
        ],
        "next": { "href": "https://example.com/book?offset=20" }
    }
}

Optionally, a link's target resource may be embedded into the current response, so clients can avoid a second request to fetch that data:

{
    "_embedded": {
        "item": [
            {
                "name": "War and Peace",
                "_links": {
                    "self": { "href": "https://example.com/book/1" },
                    "author": [
                        {
                            "href": "https://example.com/author/2",
                            "name": "Leo Tolstoy"
                        }
                    ]
                }
            }
        ]
    },
    "_links": {
        "self": { "href": "https://example.com/book" },
        "item": [
            {
                "href": "https://example.com/book/1",
                "name": "Crime and Punishment"
            },
            {
                "href": "https://example.com/book/2",
                "name": "War and Peace"
            },
            {
                "href": "https://example.com/book/3",
                "name": "Pride and Prejudice"
            }
        ],
        "next": { "href": "https://example.com/book?offset=20" }
    }
}

Design decisions

To avoid creating bespoke link relations, existing ones will be reused as appropriate, with the following source priority (most to least preferred):

  1. the IANA registry;
  2. existing namespaced relations;
  3. private relations in the https://openpublishing.com namespace.

No use of CURIEs

Despite the added verboseness of using namespaced link relationships, CURIEs are not used, to simplify the development of clients.