Five JSON REST API Link Formats Compared

In this post I intend to compare five JSON REST API data formats which implement some form of resource linking.

Three Sentence Summary (TLDR)
Web services may benefit from providing links within resource representations, but no clear consensus exists for what these links should contain. By comparing several different formats for embedding links in REST APIs, we can infer some trends which may inform us when designing or consuming REST APIs. If we generalize based on the comparison of five different readily available REST API Link formats, we may conclude that service vendors who provide links are likely to only consistently support target URLs and relation types, while other features such as embedded resource metadata, documentation, and deprecation status are less likely to be supported consistently by vendors.

Motivation

Linking in HTTP APIs is desirable (for reasons outside the scope of this article – see “Additional Reading” section for more information), but there is no clear consensus on how links should be formatted within resource representations, or what information they should include. By comparing several different readily available formats for providing links in HTTP APIs, we can get some idea of which features are common practices and which features are less used. As a vendor designing an HTTP API, or as a developer designing a generic interface for a class of HTTP APIs, this information may be helpful when deciding which link features to support.

Comparison

1. RFC 5988, Web Linking: http://tools.ietf.org/html/rfc5988
RFC 5988 does not define a concrete specification for links in JSON, but it does define syntax for specifying links in HTTP headers, which may supplement JSON resources. RFC 5988 addresses the fundamental concept of a link within an HTTP service. It was written back in 2010 and defines basic linking concepts that many other linking formats use, such as the link relation type.

RFC 5988 is well summarized in the following sentence from RFC 5988, section 3:

A link can be viewed as a statement of the form “{context IRI} has a {relation type} resource at {target IRI}, which has {target attributes}”.

Each link in RFC 5988 may contain:

  • link relation (optional)
  • target URI (required)
  • expected resource content-type
  • expected resource language
  • title (for documentation / debug purposes)

2. HAL, JSON Hypertext Application Language (http://tools.ietf.org/html/draft-kelly-json-hal-06)
HAL is a format for describing resources containing links and embedded resources. Links are represented within resources as an object mapping relation-types to one or more Link Objects, each of which may contain:

  • link relation (required, by association)
  • target URI (required; may be templated)
  • expected resource content-type
  • expected resource profile (see http://tools.ietf.org/html/rfc6906 for more information on “profile”; also conveyed as link from target resource)
  • expected resource language
  • resource deprecation status
  • title (for documentation / debug purposes)
  • name (to be used in order to distinguish link from others within context resource)

3. Collection+JSON (http://amundsen.com/media-types/collection/format/)
Collection+JSON is a format for describing collections of resources in JSON. Interestingly, even single resources are represented as Collection singletons. Links are represented as arrays of objects, each of which contain:

  • link relation (optional)
  • target URI (required)
  • name (to be used in order to distinguish link from others within context resource)
  • title (for documentation / debug purposes)
  • image flag

4. JSON Hyper-Schema (http://tools.ietf.org/html/draft-zyp-json-schema-03)
Unlike the other formats here, JSON Hyper-Schema does not define a format for resource representation. Rather, JSON Hyper-Schema is a supplemental document served alongside (and linked to) your resources, which provides additional information such as data validity rules and instructions for determining links given the information provided.

The link “description objects” which JSON Hyper-Schema allows schema authors to define may include the following information:

  • link relation (optional)
  • target URI (required)
  • URI of expected resource schema
  • expected “Accept”ed methods on resource (eg, GET, PUT)
  • expected content-type of resource
  • expected schema for request data (applies to either query string or body)

5. Home Document Format (http://tools.ietf.org/html/draft-nottingham-json-home-03)
The Home Document format is not intended to apply to all resource types; rather, it is intended to serve as a specialized “Table of Contents” or index format for an HTTP API. However, it is an interesting case because the author is very active in proposing and implementing new HTTP specifications. Home Documents are essentially just mappings of rel-types to individual link objects. Each link object may contain:

  • link relation (required, by association)
  • target URI (required; may be templated)
  • documentation concerning target URI template variables
  • URI for human-readable documentation on the resource
  • status (if deprecated or gone)
  • “hints”, expected resource behaviors (an optional collection of “advisory” / non-authoritative info which could otherwise be gleaned from a HEAD request or through trial and error; too numerous to describe in detail here)

Analysis

  • The formats disagree on what types of information should be embedded in links. Compiled here is a comprehensive list of all types of information conveyed by any of the above formats:
    • Context URI – by virtue of being embedded within a resource, these links have a context URI
    • Target URI – a URI for the target, or a mechanism for creating the URI from a template
    • Relation type – a description of the “relation” type between the context resource and the target resource
    • Target headers – including any meta-information that could otherwise be conveyed via HTTP headers, e.g., Content-Type, Accept.
    • Identification of link within resource (“name”)
    • Debug / Documentation info (“title”, “prompt”, “docs”)
    • Lifecycle Management (“deprecation”, “status”)
    • Direction for forming request payloads – (“schema”)
  • All formats support the core concept of links as described by RFC 5988 (context URI, target URI, and relation type).
  • All formats include some information which is also exposed in the target headers, arguably with the exception of Collection+JSON.
  • Other types of information (Debug/Documentation, direction for submitting requests, and lifecycle management) do not share consistent widespread support among the formats compared.

Conclusions

  • If the compared API Content Type specifications are any indicator, API vendors who implement linking will likely only agree on the basic principles of linking (Context URI, Relation, and Target URI).
  • Developers who wish to use service vendors in an interchangeable way will be best served by only exposing those core properties of a link to application logic, even if a particular vendor exposes more functionality.
  • Service vendors who wish to make efficient use of their development resources may want to implement only the basics of link functionality, and invest remaining time into documentation (especially around link relation types).
  • As a side note, JSON Hyper-Schema may be a good declarative mechanism for application developers to define links for resources in REST APIs which do not provide links.

Opinions

After reading through the specs of these (and several other) formats, I have formed the following opinions. I recognize that they are somewhat subjective; feel free to disagree with me.

  • Several of the compared specifications attempt to overload the concept of a link with other types of information that fall outside the essence of a link (i.e., a relationship between two resources). To address each type of non-essential information conveyed via links by one or more of the compared formats:
    • Debug/Documentation info may be implemented via links and custom headers on the resource.
    • Lifecycle management may be alternatively accomplished using custom headers on the target resource.
    • Direction for submitting requests may be alternatively accomplished using custom headers on the target resource.
    • Identification of a link within a resource is arguably better accomplished via more fine grained relation types, e.g., “primary source”.
  • The use case for embedding target resource metadata (eg, Content-Type) within links is similar to embedding the entire resource within the link. In both cases, the embedded data serves as a “shortcut”, providing information which is available through alternative means (i.e., via a separate GET or HEAD request).
  • Associating links with metadata related to the target resource seems to be a common desire based on the support among several of the API content-types compared. However, this support can be problematic because none of the specifications have obvious mappings between metadata in header form and metadata in link form. This redundant information in different formats makes it possible for clients to process these metadata inconsistently, or for servers to report these metadata inconsistently. More importantly, it makes it difficult for developers to create generic interfaces which expect and properly handle a basic level of embedded metadata support from several different service providers. For example, none of the formats that deal with embedded resources attempt to address cache invalidation. This subject is interesting and could be discussed at length, but embedded metadata and resources will likely become obsolete anyway when HTTP/2 sees widespread adoption.

Additional Reading

Linking in JSON, Mark Nottingham

Leave a Reply

Your email address will not be published. Required fields are marked *