Health

WTF is HAL (Hypertext Application Language)?

 

So you've found yourself making decisions about an API and are interested in Hypertext Application Language (HAL). Well, you're in the right place! I'm writing this blog post to learn as we go along, so come along for the journey. I hope you enjoy it!

Table of Contents

  1. The Background
  2. How do I use HAL?

TL;DR

Hypertext Application Language (HAL) is a convention for defining hypermedia links within JSON or XML code. It simplifies API development by making APIs more discoverable and allowing easy interaction using JSON or XML. HAL uses a special media type (application/hal+json or application/hal+xml) to indicate its usage. It facilitates linking resources, such as books and authors, by including _links objects. These links can be used to navigate between resources and perform actions. HAL offers a minimal impact approach and enables the creation of general-purpose libraries for APIs.

The Background

Let's start off with Wikipedia's definition of what Hypertext Application Language is:

Hypertext Application Language (HAL) is a convention for defining hypermedia such as links to external resources within JSON or XML code. It is documented in an Internet Draft (a "work in progress"), however, the latest version of HAL Internet-Draft expired on November 12, 2016. The standard was initially proposed in June 2012 specifically for use with JSON and has since become available in two variations, JSON and XML. The two associated MIME types are media type: application/hal+xml and media type: application/hal+json.

HAL was created to be simple to use and easily applicable across different domains by avoiding the need to impose any requirements on how the project be structured. Maintaining this minimal impact approach, HAL has enabled developers to create general-purpose libraries that can be easily incorporated into any API that uses HAL.

APIs that adopt HAL simplify the use of open-source libraries and make it possible to interact with the API using JSON or XML. The alternative would be having to develop a proprietary format, which in turn forces developers to learn how to use yet another foreign format.

From this point on, Hypertext Application Language will be referred to as HAL.

So, to unpack that and to make it easier to read, here is my interpretation of this:

  • HAL is used to handle links across your API and make your API more discoverable.
  • HAL can be used for both internal routes as well as routes external to your application, despite being only mentioned here as external.
  • HAL has a special media type application/hal+json or application/xml+json. This should be used to let clients of your API know that you are using HAL.

How do I use HAL?

Let's start with an example of a bookstore.

Endpoint: GET /books/{bookId}

Response:

{

  "id": "1",

  "title": "The Hobbit",

  "genre": "Fantasy",

  "author": {

    "id": "1",

    "name": "J.R.R. Tolkien",

    "_links": {

      "self": {

        "href": "/authors/1"

      }

    }

  },

  "_links": {

    "self": {

      "href": "/books/1"

    }

  }

}

When you send a GET request to retrieve information about a specific book with the ID 1, the API responds with the book's details, including its title, genre, and the author associated with it. The response follows the HAL format. The book resource includes a link to the author's resource using the _links object, where the self link points to the URL for the author resource.

Endpoint: GET /authors/{authorId}

Response:

{

  "id": "1",

  "name": "J.R.R. Tolkien",

  "books": [

    {

      "id": "1",

      "title": "The Hobbit",

      "_links": {

        "self": {

          "href": "/books/1"

        }

      }

    },

    {

      "id": "2",

      "title": "The Lord of the Rings",

      "_links": {

        "self": {

          "href": "/books/2"

        }

      }

    }

  ],

  "_links": {

    "self": {

      "href": "/authors/1"

    }

  }

}

When you send a GET request to retrieve information about a specific author with the ID 1, the API responds with the author's details, including their name and the books they have written. The response follows the HAL format. The author resource includes a list of books, each represented as a separate object with its own _links object. These links point to the URLs for the respective book resources.

_links

The _links key can include a wide array of keys. In the book example, we could add a next key to show the next book in the series or even a prev to show the previous book in the series.

It's also a great place to link together actions. For example, editing a book would now include:

{

  "id": "1",

  "title": "The Hobbit",

  "_links": {

    "self": {

      "href": "/books/1"

    },

    "next": {

      "href": "/books/2"

    },

    "edit": {

      "href": "/books/2/edit"

    }

  }

}

Your Next Step

Do your career a favor. Join the DEV community.

It takes one minute and is worth it for your career.

HAL - Hypertext Application Language

A lean hypermedia type

Author: Mike Kelly mike@stateless.co Created: 2011-06-13 Updated: 2013-09-18

Summary: HAL is a simple format that gives a consistent and easy way to hyperlink between resources in your API. Adopting HAL will make your API explorable, and its documentation easily discoverable from within the API itself. In short, it will make your API easier to work with and therefore more attractive to client developers.

APIs that adopt HAL can be easily served and consumed using open-source libraries available for most major programming languages. It's also simple enough that you can just deal with it as you would any other JSON.

About The Author

Mike Kelly is a software engineer from the UK. He runs an API consultancy helping companies design and build beautiful APIs that developers love.

Quick Links

General Description

HAL provides a set of conventions for expressing hyperlinks in either JSON or XML. The rest of a HAL document is just plain old JSON or XML. Instead of using ad-hoc structures, or spending valuable time designing your own format, you can adopt HAL's conventions and focus on building and documenting the data and transitions that make up your API.

HAL is a little bit like HTML for machines, in that it is generic and designed to drive many different types of applications via hyperlinks. The difference is that HTML has features for helping 'human actors' move through a web application to achieve their goals, whereas HAL is intended for helping 'automated actors' move through a web API to achieve their goals.

Having said that, HAL is actually very human-friendly too. Its conventions make the documentation for an API discoverable from the API messages themselves. This makes it possible for developers to jump straight into a HAL-based API and explore its capabilities, without the cognitive overhead of having to map some out-of-band documentation onto their journey.

Examples

The example below is how you might represent a collection of orders with hal+json. Things to look for:

  • The URI of the main resource being represented (/orders) expressed with a self link
  • The next link pointing to the next page of orders
  • A templated link called ea:find for searching orders by ID
  • The multiple ea:admin link objects contained in an array
  • Two properties of the orders collection; currentlyProcessing and shippedToday
  • Embedded order resources with their own links and properties
  • The compact URI (curie) named ea for expanding the name of the links to their documentation URL

application/hal+json:

{

    "_links": {

        "self": { "href": "/orders" },

        "curies": [{ "name": "ea", "href": "http://example.com/docs/rels/{rel}", "templated": true }],

        "next": { "href": "/orders?page=2" },

        "ea:find": {

            "href": "/orders{?id}",

            "templated": true

        },

        "ea:admin": [{

            "href": "/admins/2",

            "title": "Fred"

        }, {

            "href": "/admins/5",

            "title": "Kate"

        }]

    },

    "currentlyProcessing": 14,

    "shippedToday": 20,

    "_embedded": {

        "ea:order": [{

            "_links": {

                "self": { "href": "/orders/123" },

                "ea:basket": { "href": "/baskets/98712" },

                "ea:customer": { "href": "/customers/7809" }

            },

            "total": 30.00,

            "currency": "USD",

            "status": "shipped"

        }, {

            "_links": {

                "self": { "href": "/orders/124" },

                "ea:basket": { "href": "/baskets/97213" },

                "ea:customer": { "href": "/customers/12369" }

            },

            "total": 20.00,

            "currency": "USD",

            "status": "processing"

        }]

    }

}

This is just a brief overview to get you started with HAL. There are many resources available online for more in-depth information and practical applications. Explore the provided links and start integrating HAL into your API to make it more discoverable and easier to use!

Post a Comment

0 Comments