A Common Link component for JSON APIs

119 views
Skip to first unread message

Filippos Vasilakis

unread,
Nov 10, 2017, 7:29:10 AM11/10/17
to API Craft
Hi! Intrigued by @dret's presentation Let's Fix HAL http://dret.net/lectures/restfest-2017/fixing-hal, I started thinking more about the fact that we are in 2017 and we still don't share common components across different JSON-based APIs. Basically I believe that we should opt for a component-based API building instead of re-inventing the wheel all the time by creating monolithic Media Types.

To give you an example, take a look of linking in different API specs/Media Types. As defined by RFC 8288 (which is a clearer version of RFC 5988 published in 2010), section 2:
a link is a typed connection between two resources and is comprised of:
  • a link context,
  • a link relation type (Section 2.1),
  • a link target, and
  • optionally, target attributes (Section 2.2).
A link can be viewed as a statement of the form "link context has a link relation type resource at link target, which has target attributes".

If we take a look in most common API specs:
  • JSONAPI provides links of a resource under "links" element which must be an object. Each element in the object can be a link, with the attribute being the relation type and the value can be either a string or object with 2 elements, "href" and "meta".
  • HAL provides links of a resource under "_links" element which must be an object. Each element in the object can be a link, with the attribute being the relation type and the value of that is an object containing the link under "href" attribute.
    • More info: http://stateless.co/hal_specification.html
    • example: {"_links":{"next":{"href":"/page=2"}}}
    • HAL also provides curies that @dret had a nice presentation showing how they are broken, but I am not very interested in those links as they are targeted for humans
  • Siren provides links of a resource under "links" element which must be an array. Each object in the array must have at least the Web Linking elements, namely "rel", "href", "type". along with some Siren-specific attributes. Note that "rel" must be an array.
  • JSON Hyper Schemas provides links of a resource under "links" element which must be an array. Each object in the array must have at least the Web Linking elements, namely "rel", "href", "type". along with some other schema-specific attributes
    • More info: http://json-schema.org/work-in-progress/WIP-jsonschema-hyperschema.html#rfc.section.6
    • example: {"links":[{"rel":"self","href":"things/{id}","templateRequired":["id"],"targetSchema":{"$ref":"#"}}]}
    • Note that JSON Hyper Schemas is not a Media Type and has some more logic on how to "build" the link with other attributes defined in higher levels. But I still think it should share a common structure (the href value could have a different meaning though) derived from a common Link component.


While all those Link descriptions could achieve the same goal (i.e. support all parts of a link defined in RFCs) they are quite different in implementation and not compatible. And that's a pity because links are one of the simplest components that can be found in hypermedia formats. In contrast to JSON, XML had solved years ago the issue of linking from its conception through XLinks, a common component that any XML-based API can use.

No matter how much we have tried, JSON limits us a lot when it comes to hypermedia. The problem is JSON itself that makes it rather difficult to create reusable components in a nice way because it's basically a key-value format, targeted for data structures mostly. For instance, there isn't inherent support for having tags, the solution to that is to create more key/value elements. So we have been struggling with hypermedia-(s)ing JSON, and we do that by appending hypermedia information to the response itself or using wrapper formats like JSON-LD, Hydra, that come on top of JSON. 

If JSON is not, fundamentally, a hypermedia format, is this the way to go when building JSON APIs ? I am not sure about that. By having self-descriptiveness and evolvement constraints, I think a resource-centric design as I described in https://introspected.rest would make more sense.

But in any case, an alternative solution, and probably more plausible to the masses would be to start creating reusable Link and Form components for JSON-based hypermedia APIs. To me, it seems very impractical that every API and API spec defines these 2 things differently. What do you think ?
Reply all
Reply to author
Forward
0 new messages