Since 2016 I’ve been working on a javascript library to make it easier to work
with HAL services. Yesterday I realized I implemented all the
features I wanted for a 1.0 , and also that I never talked about it on
this blog.

So this evening I released 1.0, and also share some information about it here.
It’s been almost a year since I blogged! Really gotta get back on this horse.

A bit of background

Nearly 2 years ago we implemented a new API at a company I worked at. We chose
to go the REST/hypermedia/HATEOAS route and use HAL as the primary

I had a drive to try and see what a good client for this would look like, so
I decided to write my own in my free .

This client is written in Javacript, works in node.js and in browsers. We use
it as a real client, but also doing black- testing of API’s.

A summarized list of features

  • It parses HAL _links and provides a convenient API for following links.
  • Uses the Fetch API for HTTP requests and is heavily promise-based.
  • Automatically parsed items in _embedded and stores them in a cache. The
    nice thing about this is that if a server chooses to embed certain items,
    the client will automatically adapt and ‘upgrade’ to take advantage of this,
    resulting in less requests.
  • Recognizes application/problem+json responses and automatically
    converts them to exceptions.
  • Supports Basic auth, Bearer tokens.
  • Also implements some of OAuth2, the password,
    client_credentials grant types and will automatically refresh expired
    access tokens if a refresh token was provided.
  • Supports HTTP Link: headers and merges them in with HAL links,
    you to follow links on non-HAL or non-JSON resources.
  • Similarly, if given a HTML document it will extract all <link> and
    <a> tags with rel= attributes.

How does it work?

Generally with REST you’ll want to ‘discover’ urls based on link relationships,
and not hardcode them. This is the main focus of the API.

The following sample does the following:

  1. Create a new client and specify the ‘bookmark url’ of the API to
  2. Find a collection of articles using rel="articleCollection".
  3. Grab the first article in that collection (generally items in a collection
    use rel="item". See RFC6573).
  4. Do a GET request on the article, and afterwards follow the rel="author"
  5. Lastly, change the name of the author by doing a PUT request.
const  = new Ketting('');

// Ketting uses a special promise that has a `follow` function so it can be
// chained to do multiple hops.
const articleResource = await ketting.follow('articleCollection').follow('item');
const articleBody = await article.get();

const authorResource = await articleResource.follow('author');
const authorBody = await authorResource.get(); = 'Evert Pot';

await authorResource.put(authorBody);

A few notes:

  • Any of these hops could have been HTML documents, HAL documents or any
    resource with a Link header. Only the last one (author) really had to be
    JSON, because we’re parsing it and changing it.
  • If any of the followed links appeared in _embedded, they’re stored in a
    local cache and those HTTP requests would have been skipped.
  • Ketting will wait till the last possible moment to do a HTTP request.
    Sometimes it’s a bit surprising when the actual HTTP request happens.
    following a link generally does not.

Anyway, I hope this is interesting to other folks! Special thanks to @mhum
for his significant contributions.

Some things that might happen for a 2.0 version:

  • Total conversion to Typescript. I went from a sceptic to a believer.
  • Maybe support for the SIREN and Atom format.

Source link


Please enter your comment!
Please enter your name here