Skip to content

Latest commit

 

History

History

linker

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

@hateoas/linker

npm version Continuous integration status Maintainability Test Coverage

Easily construct HATEOAS HAL (templated) links with zero deps

Installation

npm install --save @hateoas/linker

Example Usage

import { link, origin, param, paramValue, segment } from '@hateoas/linker'

// consider request on /users
getUser(request, response) {
    // ...
    const selfLink = link(req, param('active')) // http://example.com/users{?active}
    // ...
}

// consider request on /users/31
getUser(request, response) {
    // ...
    const selfLink = link(req) // http://example.com/users/31
    const activateLink = link(selfLink, 'activate') // http://example.com/users/31/activate
    // ...
}

API

The linker API is made to reuse outputs of link calls, so you can build link on top of link. The link itself is a class and it can be turned into string by calling .toString(), .toJSON or just using default JavaScript JSON/string conversion.

Trivial link

Creates link various properties passed as arguments

link('foo')
// "/foo"

Link with origin

By passing origin, the linker will construct absolute URL.

link(origin('https://example.com'), 'foo')
// "https://example.com/foo"

Passing HTTPRequest or IncomingMessage instance into the API will automatically set the link origin

link(req, 'foo')
// "http://example.com/foo"

Link with parameters

By passing param, the linker will construct templated URL with optional query string parameters.

link('users', param('active'))
// { href: "/users{?active}", templated: true }

Multiple params can be passed

link('users', param('active', 'funny')) 
// { href: "/users{?active,funny}", templated: true }

Link with parameter values

By passing paramValue, the linker will construct URL with query string parameter values.

link('users', paramValue({ active: true })
// "/users?active=true"

You can combine this with other params, making templated URL.

link('users', paramValue({ active: true }), param('funny'))
// { href: "/users?active=true{&funny}", templated: true }

Link with path segment

By passing segment, the linker will construct templated URL with variable path segments, allowing to link to specific path by template.

link('users', segment('userId'))
// { href: "/users/{userId}", templated: true }

Bigger example

const base = link(req, 'users')
// "http://example.com/users"
const selfLink = link(base, param('active', 'funny'))
// "http://example.com/users{?active,funny}"
const entityLink = link(base, segment('userId'))
// "http://example.com/users/{userId}"
const activateLink = link(entityLink, 'activate')
// "http://example.com/users/{userId}/activate"

Inject link into entity

Use linkObject method, to conveniently inject links into objects.

import { link, linkObject } from '@hateoas/linker'

const user = {
  name: 'foo',
  email: '[email protected]',
}

// Assume `request` is HTTPRequest instance
const self = link(request, 'users', user.name)
const activate = link(self, 'activate')

linkObject(user, { self, activate })

/*
{
  name: 'foo',
  email: '[email protected]',
  _links: {
    self: 'http://example.com/users/foo',
    activate: 'http://example.com/users/foo/activate',
  },
*/
})

Inject link into entity collection

Use linkCollection method to conventiently inject links into collections.

import { link, linkCollection } from '@hateoas/linker'

// Assume `request` is HTTPRequest instance
// Assume, there are two already linked users
const self = link(request, 'users', param('active', 'funny'))

linkCollection(users, { self })

/*
{
  name: 'foo',
  email: '[email protected]',
  _links: {
    self: {
      href: 'http://example.com/users{?active,funny}',
      templated: true,
    },
  },
*/
})