This is in beta. If you find something wrong, let us know

Hypermedia

Hypermedia - Linked Data

Hypermedia links in APIs are links in the response payload that inform the consumers to what contents can be retrieved. Though simple in concept hypermedia links in APIs allow consumers to locate resource without the need to have an upfront understanding of the resource and its relationship.

This is similar to the navigation of a web page. The user is not expected to know the structure of the web page prior to visiting. They can simply browse to the home page and the navigation lets them browse the site as required.

APIs that do not provide links are difficult to use and expect the consumer to refer to the documentation.

Example:


GET /namespace/v1/employees

//200 OK

{
  "total_records" : "1",
  "_links": [{
      "href" : "/namespace/v1/employees",
      "rel" : "self"
  }],
  "employees": [{
    "name" : "John Smith",
    "_links": [{
        "href" : "/namespace/v1/employees/john-smith",
        "rel" : "self"
    }]
  }]
}

HATEOAS

Hypermedia As The Engine Of Application State is the concept of representing allowable actions as hyperlinks associated with resource. Similar to Hypermedia Linked Data concept the links defined in the response data represents state transitions that are available from that current state to adjacent states.

{
  "account_number":"12345",
  "balance": 100.00,
  "_links":[
    {"rel": " **deposit**",  "href":"/accounts/12345/deposit"},
    {"rel": " **withdraw**", "href":"/accounts/12345/withdraw"},
    {"rel": " **transfer**", "href":"/accounts/12345/transfer"}
  ]
}

But if the same account is overdrawn by 25 then the only allowed action is deposit:

{
  "account_number":"12345",
  "balance": -25.00,
  "_links":[{
    "rel": "deposit",
    "href":"/accounts/12345/deposit"
  }]
}

Deciding to implement HATEOAS designs in your API is dependent on the readiness of the clients to consume HATEOAS and the design and implementation effort.

Hypermedia Compliant API

A hypermedia compliant API provides consumers with an accessible a state machine of the transitions that are available for them to use.

In APIs, request methods such as DELETE, PATCH, POST and PUT initiate a transition in the state of a resource. A GET request MUST never change the state of the resource that is retrieved.

In order to provide a better experience for API consumers, API designers SHOULD provide a list of state transitions that are available for each resource in the _links array.

An example of an API that exposes a set of operations to manage a user account lifecycle and implements the HATEOAS interface constraint is as follows:

A client starts their interaction with a service through the URI /users. This fixed URI supports both GET and POST operations. The client decides to do a POST operation to create a user in the system.

Request

POST https://gw.api.gov.au/dept-xyz/v1/users

{
    "first_name": "John",
    "last_name" : "smith",
    ...
}

Response

The API creates a new user from the input and returns the following links to the client in the response.

HTTP/1.1 201 CREATED
Content-Type: application/json
Location: https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI
...

{
  "_links": [
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "self",
          "method" : "GET"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "delete",
          "method": "DELETE"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "replace",
          "method": "PUT"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "edit",
          "method": "PATCH"
      }
  ]

}

A client can store these links in its database for later use.

A client may then want to display a set of users and their details before the admin decides to delete one of the users. So the client does a GET to the same fixed URI /users.

Request

GET https://gw.api.gov.au/dept-xyz/v1/users

The API returns all the users in the system with respective self links.

Response

HTTP/1.1 200 OK
Content-Type: application/json
...

{
    "total_records": "2",
    "users": [
      {
          "first_name": "John",
          "last_name": "Greenwood",
          ...
          "_links": [
              {
                  "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
                  "rel": "self"
              }
          ]
      },
      {
          "first_name": "David",
          "last_name": "Brown",
          ...
          "_links": [
              {
                  "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-MDFSKFGIFJ86DSF",
                  "rel": "self"
              }
          ]
      }
    ]
}

The client MAY follow the self link of each user and figure out all the possible operations that it can perform on the user resource.

Request

GET https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI

Response

HTTP/1.1 200 OK
Content-Type: application/json
...
{
    "first_name": "John",
    "last_name": "Smith",
    ...
    "_links": [
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "self",
          "method" : "GET"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "delete",
          "method": "DELETE"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "replace",
          "method": "PUT"
      },
      {
          "href": "https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI",
          "rel": "edit",
          "method": "PATCH"
      }
    ]
}

To delete the user, the client retrieves the URI of the link relation type delete from its data store and performs a delete operation on the URI.

Request

DELETE https://gw.api.gov.au/dept-xyz/v1/users/ALT-JFWXHGUV7VI

In summary:

The mere presence of links does not decouple a client from having to learn the data required to make requests for a transition and all associated link semantics particularly for POST/PUT/PATCH operations. An API MUST provide documentation to clearly describe all the links, link relation types and request response formats for each of the URIs.

Links MUST be described using the Link Description Object (LDO) schema. An LDO describes a single link relation in the links array. Following is brief description for properties of Link Description Object.

href

rel

method

title

A Link Relation Type serves as an identifier for a link. An API MUST assign a meaningful link relation type that unambiguously describes the semantics of the link. Clients use the relevant Link Relation Type in order to identify the link to use from a representation.

When the semantics of a Link Relation Type defined in IANA's list of standardized link relations matches with the one you want to define then it MUST be used.

The table below describes some of the commonly used link relation types. It also lists some additional link relation types defined by these guidelines.

Link Relation Type Description
self Conveys an identifier for the link's context. Usually a link pointing to the resource itself.
create Refers to a link that can be used to create a new resource.
edit Refers to editing (or partially updating) the representation identified by the link. Use this to represent a PATCH operation link.
delete Refers to deleting a resource identified by the link. Use this Extended link relation type to represent a DELETE operation link.
replace Refers to completely update (or replace) the representation identified by the link. Use this Extended link relation type to represent a PUT operation link.
first Refers to the first page of the result list.
last Refers to the last page of the result list provided total_required is specified as a query parameter.
next Refers to the next page of the result list.
prev Refers to the previous page of the result list.
collection Refers to a collections resource (e.g /v1/users).
latest-version Points to a resource containing the latest (e.g., current) version.
search Refers to a resource that can be used to search through the link's context and related resources.
up Refers to a parent resource in a hierarchy of resources.

For all controller style complex operations, the controller action name must be used as the link relation type (e.g. activate,cancel,send).