Hypermedia and HAL

Joost Cassee

joost@cassee.net

@jcassee

jcassee.com

Human Environment and Transport Inspectorate
October 19, 2015

I will talk about

  • modeling business logic as state manipulation
     
  • using links and profiles to create a loosely coupled web of API resources
     
  • keeping an API malleable while maintaining backward compatibility

Resource

URI

http://example.com/ship/9334026

"An entity"

Representation

{
  "name": "VOS PROMINENCE",
  "imo": 9334026,
  "type": "cargo"
}

Media Type

application/json

Type

Profile
http://example.com/profiles/ship

"It is a ship"

The resource identified by http://example.com/ship/9334026

{
  "name": "VOS PROMINENCE",
  "imo": 9334026,
  "type": "cargo"
}

and is represented as application/json by

has profile http://example.com/profiles/ship

Representational State

... Transfer

A resource identified by a http/https URL

can be manipulated using HTTP methods

GET

PUT

DELETE

PATCH

POST

Retreive a representation

Store a representation

Delete a resource

Update a resource

"Process" a representation

}

idempotent

REST is CRUD

... for the most part

Expose business logic as state manipulation

Hypertext reference

href

http://example.com/company/3342

"That entity over there"

References in resource state

{
  "name": "VOS PROMINENCE",
  "imo": 9334026,
  "type": "cargo",
  "ownerHref": "http://example.com/company/3342"
}

"That is the owner"

(semantics described by the profile)

Linking

Relation
http://example.com/relations/owner

"It has an owner"

The resource identified by http://example.com/ship/9334026

to the resource identified by http://example.com/company/3342

has relation http://example.com/relations/owner

HAL

Hypermedia Application Language

application/hal+json

Why HAL?

  • Links in response body:
    Better client support than Link headers
     
  • Embedded resources:
    Reduce the number of requests
{
  "name": "VOS PROMINENCE",
  "imo": 9334026,
  "type": "cargo",
  ...
{
  "name": "VOS PROMINENCE",
  "imo": 9334026,
  "type": "cargo",
  "_links": {
    "self": {
      "href": "http://example.com/ship/9334026"
    },
    "profile": {
      "href": "http://example.com/profiles/ship"
    },
    "http://example.com/relations/owner": {
      "href": "http://example.com/company/3342"
    }
  },
  ...
{
  ...
  "_embedded": {
    "http://example.com/relations/owner": {
      "name": "Vroon B.V.",
      "_links": {
        "self": {
          "href": "http://example.com/company/3342"
        },
        "profile": {
          "href": "http://example.com/profiles/company"
        }
      }
    }
  }
}

State reference

  • Part of resource state
  • Defined by profile
  • Mutable by client
  • Removal is backward-incompatible

Link relation

  • Part of API wiring
  • Defined by relation
  • Not mutable by client
  • Can be deprecated and removed

vs.

{
  "_links": {
    "rel": { "href": "uri" }
  }
}
{
  "property": "uri"
}

HATEOAS

Hypertext As The Engine Of Application State

"Use links to traverse the API"

Elements of a hypermedia API

  1. The URI of the root resource
  2. A set of relations
  3. A set of profiles

"It's not an API, it's a protocol!"

Hypermedia clients ...

  • know about profilesrelations and root URI
     
  • treat URIs as opaque
     
  • assume backward compatibility of state
     
  • let presence of links drive interactions
    (recover gracefully from missing links)

Hypermedia servers ...

  • decide what links to provide, based on
    • user roles
    • service availability
  • decide what resources to embed, based on
    • business workflow
    • client-server negotiation

URI Templates

{
  "_links": {
    "http://example.com/relations/owner": {
      "href": "http://example.com/company/3342"
    },
    "http://example.com/relations/crew-search": {
      "href": "http://example.com/ship/9334026/crew{?name,nationality}",
      "templated": true
    }
  }
}

Link parameters

{
  "_links": {
    "http://example.com/relations/owner": {
      "href": "http://example.com/company/3342",
      "type": "application/hal+json",
      "methods": ["GET"]
    }
  }
}

Hypermedia APIs ...

give you

  • reuse of relations and profiles
  • seamless navigation across services
  • well-defined API evolution mechanism
  • compatibility with server push models

require

  • a departure from URL-centric design
  • client robustness w.r.t. links
  • design of API wiring

Reuse of profiles and relations

{
  "_links": {
    "self": { "href": "http://example.com/users/john" },
    "profile": { "href": "http://profiles.example.com/person" }
  }
}
{
  "_links": {
    "self": { "href": "http://example.com/clients/4335/contact" },
    "profile": { "href": "http://profiles.example.com/person" }
  }
}

Navigation across services

{
  ...
  "_links": {
    "self": {
      "href": "http://example.com/ship/9334026"
    },
    "http://example.com/relations/owner": {
      "href": "http://companies.example.com/3342"
    }
  }
}

API evolution (1) - topology change

{
"_links": {
  "http://example.com/relations/owner": {
    "href": "http://example.com/company/3342"
  }
}
{
"_links": {
  "http://example.com/relations/owner": {
    "href": "http://companies.example.com/3342"
  }
}

API evolution (2) - concept change

{
  "_links" : {
    "http://example.com/relations/owner" : {
      "href" : "http://example.com/company/3342",
      "deprecation": "http://example.com/docs/deprecated/owner.html"
    },
    "http://example.com/relations/ownership" : {
      "href" : "http://example.com/ship/9334026/ownership/3"
    }
  }
}

Effect on development process

  • Incremental and iterative API design

     
  • Decoupling of server and client development

Server push with STOMP

SUBSCRIBE
id:0
destination:http://example.com/company/3342/ships
MESSAGE
subscription:0
message-id:007
destination:http://example.com/company/3342/ships
content-type:application/hal+json

{
  "total": 5,
  ...

I talked about

  • modeling business logic as state manipulation

  • using links and profiles to create a loosely coupled web of API resources

  • keeping an API malleable while maintaining backward compatibility

Hypermedia with HAL

By Joost Cassee

Hypermedia with HAL

Presentation at the Dutch Human Environment and Transport Inspectorate.

  • 2,452