Update 5/12/2016: Stormpath now secures authentication to your API- without code!

Also, we have some awesome new resources for API developers building user management:

Also, we’d love to have you try out JJWT, a Java library providing end-to-end JWT creation and verification, developed by our very own Les Hazlewood. Forever free and open-source (Apache License, Version 2.0), JJWT is simple to use and understand.

 

While the specifications for both XML (via XLink) and HTML (via anchor tags, the “a” element) have hypertext references built into their respective specifications, there is no such JSON-specific specification for linking. This means there are many different ways to add hypertext to your REST + JSON API. Some examples include JSON APICollection+JSON, HAL, and Siren.

But Stormpath has our own approach, which is particularly simple and elegant while enabling a very powerful feature common to REST APIs. We will cover it in this post in case you want to use it in your own API.

Link Triforce - 16-bit nerd out

Why use Linking

Linking can help with discoverability and use-case scalability. Presenting the fully qualified URL for every resource aids discoverability by allowing for new resources to be consumed by just embedding a new reference (link). This works well for JSON because JSON is schema-less; adding new fields will not break functionality and will maintain backwards compatibility.

Fortunately, if a resource’s endpoint changes, the new URL will be returned and consumed as though nothing happened, which aids scalability. Additionally, providers should support 302 redirects for deprecated URLs to ensure clients with older URLs still work. Since virtually every type of web client can read a URL, developers do not need to use any additional libraries to create or parse the URLs.

Pagination is a great example of when to use linking when returning resource collections. Developers working with your API might not know how pagination works or know how to build the URL for the next set of results. Instead, you can provide them links that automatically support pagination. Here is an example of a paginated collection of users where the pages are more easily discoverable:

In this response, you can see the items property contains all the resource objects from the current page. You can access the current offset and limit so you can construct the next or previous page link if you want to. But if you don’t know how to use those properties, the first, previous, next, and last page links are available for you to use immediately. This makes it simple for a client to page through your resource collection results easily. In other words, the pages are more easily discoverable because you provided links for them already.

As we mentioned, there is no JSON standard for hypertext references, so we have to define our own technique. We have a really simple and concise implementation. Here is an example of how an account resource is returned by the Stormpath API:

This Account resource and every other JSON resource will always have an href property, which is the fully qualified canonical URL where that resource resides. Whenever you see an href property, you know you can access that resource by executing a GET request to the resource’s URL.

This holds true for resource references too. Notice the directory property in the above example. The directory property is a complex object that itself has an href attribute as well. Because the directory object has an href property, we know it is a resource itself, and the fact that an href is available means we have a direct reference or ‘link’ to that resource.

For those familiar with XLink and HTML anchors, you’ll recall that there is a ‘rel’ (short for ‘relation’) attribute that can be specified, indicating the relation – or purpose – of the reference:

<a href=”https://host/help.html” rel=”help”/>

Here the help relation attribute value indicates the referenced URL can be used to access context-sensitive help documentation.

But things can be even more succinct in JSON. What is interesting about the directory property above is that the JSON property name itself already indicates the purpose of the reference! The JSON property name can be an implicit/automatic ‘relation’ definition.

Alternatives

As you see above, we use the name of the property to indicate the relationship of the URL. For contrast, you can see how this differs from a HAL example below, which shows all of the links defined in a separate array of objects.

Although this provides a centralized place to store all the relationships, the JSON response becomes more verbose and requires you to context switch as you review the document. Instead of just having a simple object with name-value pairs, some of which are references (as Stormpath has), you now have an array of objects, each object having a “rel” and “link” tag.

Why do we prefer our approach over the HAL technique? The href technique becomes particularly valuable when it comes to Resource Expansion (aka ‘link’ expansion).

Resource Expansion

Resource expansion can be compared to eager loading in the database realm. Both offer ways to load a target resource as well as other resources related to it. REST API callers should be encouraged to use resource expansion when they know they are going to need the extra information. This will reduce the amount of API calls as well as the amount of traffic to and from your API server. Resource expansion might be avoided, however, when you want to reduce the amount of information returned or if you are unsure if you will need the additional resource object.

Let’s revisit the previous account resource with the directory link. Let’s say we support an expand query parameter that tells the server, “not only do I want the account, but I also want the account’s parent directory expanded in line, in a single response”. For example:

See how the directory has been expanded and fully included in the response payload?

Why is this really nice? Because REST clients don’t have to implement special processing logic to check different properties for expanded resources. REST clients only have to worry about one thing when encountering a nested object property: Does the nested object have only an href property?

If yes, then it is clearly a link, and it can be retrieved via a GET request.
If no (other properties exist as well), then it has already been expanded in line, and no further request to the server is required.

We believe this is more intuitive and easier to understand for humans reading the JSON payload, as well as easier to process for machine/REST clients that need to figure out how to interact with resources further. In our example above, the directory property will always be the placeholder for the directory, expanded or not. There is nowhere else in the document for a client to look to find out about links.

While the HAL approach can be a valid technique (a separate array of links), we feel it is less convenient and less readable than the in-line property technique, especially if you support resource expansion; expanding a link in the HAL links array means that the array is no longer a link array – it is an array of some links, some expanded resources. We feel this isn’t as intuitive and self-evident as using in-line properties with self-documenting relations.

Stormpath has multiple ways to reach resource expansion targets, reducing the amount of multiple calls. Here are some examples:

  • Expanding Multiple References:
    GET /v1/accounts/ZugcG3JHQFOTKGEXAMPLE?expand=directory,tenant
  • Expanding Collection References:
    GET /v1/accounts/ZugcG3JHQFOTKGEXAMPLE?expand=groups(offset:0,limit:10)
  • Expansion Combinations:
    GET /v1/accounts/ZugcG3JHQFOTKGEXAMPLE?expand=directory,groups(offset:0,limit:10)

Read more about Stormpath Reference Expansion in our API Documentation.