Introduction to the JSON API

JSONAPI was originally drafted in May 2013 by Yehuda Katz and reached stable in May 2015, and it is about making your API calls efficient. You can fetch data as you need, adding or removing attributes or relations as your requirements change. This minimizes the amount of data and round trips needed when making API calls.

JSON API documents work as any other API format, you send a request to an endpoint and receive your document. The JSON API specification defines how resources are structured. This structure helps in normalizing how you consume the API.

For example when you make a call to the resource articles through a simple GET request.

Seems simple enough. The author relationship includes a link to the relationship itself and some basic information about the relation. Using the links in the document you can retrieve information on the related resources.

But this is only scratching the surface. There are a quite a few features which make JSON API so lovely to use.

To reduce the number of HTTP requests, servers MAY allow responses that include related resources along with the requested primary resources. Such responses are called “compound documents”.

A compound document is a resource which includes the data of included relations. For example, when requesting an article as shown earlier it may include the data of the author so you don’t need a second call to fetch the author of the article.

This is awesome for a few reasons. Getting the full data of a resource you want to consume in one go is unheard of unless specific endpoints are programmed. On the server side of things, caching and invalidating a request like this is easy.

If you look at the included property you see all the related resources for the article. Every included document has a type property which defines which type of resource is returned and a link to the endpoint for the document.

It might feel weird to refer to the author relation in the article only by id and type and loading the related people resource from the included tag. But imagine when there are multiple articles referring to the same author, the document only includes the referred people once in the included data. Pretty efficient!

In the above example, the server includes all relations in the response, but you might not want this by default since this bloats the responses a bit. For this reason, the specification provides a way to specify what relations should be included in the response.

For example, if you only need the author relationship included you can just call the endpoint with the include request parameter. This will tell the server to only send the specified relation with the response.

If you need multiple relationships you separate the relations with a comma (,).When defining the includes you can go even further and include nested relations. For example, you want comments, with the authors of the comments you can just include comments.author:

This flexibility makes fetching the correct resources a breeze allowing you to tweak the results as needed.

When you are using compound documents your request could get large, fast. Especially when the included relationships contain a lot of data. Most of the time you do not need every single attribute defined in the resources but only want things like author names. JSON API provides sparse fieldsets for this use case.

You can specify the fields that are fetched by setting the fields request parameter. The format is fields[TYPE], so you can specify per resource type what fields you need.

Pagination

If the server supports pagination it will supply a few extra meta attributes with pagination information. The server can decide how to paginate themselves, be it through an offset, or direct page numbers. An example of an implementation uses the required links to other pages and includes some metadata in the meta tag.

Filtering

The spec says little about filtering, it just states there may be a parameter which is called filter which is used to fulfil filtering on the server. The implementation is specific for the server and can be anything.

When you understand the structure of documents, creating and updating resources is a breeze. It uses the standard HTTP verbs to communicate the desired action of the request. GET for fetching, POST for creating, PATCH for (partial) updating and DELETE for deleting resources.

Updating resources

When updating a resource it will update the posted fields to the new values. Values that are not included in the request will not be updated.

Updating relationships

It is possible to update relationships in 2 ways. One way is to include the relation in the PATCH request. The same way as you have seen earlier. Another way is using the specific relationship endpoint.

Deleting resources

There isn’t much to say about deleting resources, you just send a DELETEcall to the endpoint.

DELETE /photos/1 HTTP/1.1
Accept: application/vnd.api+json

If you want to learn more about the details of {json:api} and its usage, check out jsonapi.org. Their specification is quite clear, although there are a lot of features that are not mandatory for servers to implement. On their site, they also maintain a list of client and server implementations for you to get up and running quickly.

They are currently working on version 1.1 of the specification. It will be 100% backwards compatible with version 1.0, only adding new features, breaking nothing.

Hopefully, you’ve learned what makes this specification awesome. Personally, I love the structure, consistency and flexibility, this makes communicating with an API a lot easier. You always know what to expect, and don’t need loads of requests to get your data.