API ArchitectureThe benefits of using JSON API

In the world of API craftsmanship, there is no more hotly debated area than design. From REST, gRPC to GraphQL, there are many ways to design and standardize web API interactions. Today, we turn our attention to another approach, JSON API, the specification detailed at JSONAPI.org for building APIs.

The JSON API described at JSONAPI.org is great for making your JSON response formats more consistent. Aimed at increasing productivity and efficiency, JSON API is touted for its efficient caching capabilities that can eliminate redundant server requests.

In this post, we’ll define what a JSON API is and see how it can be used to build efficient APIs. We’ll cover some of the key benefits of the JSON API and see how the specification is used in practice with a case study from FitBit. Hopefully this overview will introduce those new to the JSON API and help you decide if it’s the right fit for your API scenario.

What is JSON API (JSONAPI.org)?

JSON API is a format suitable for HTTP. It describes how the client should request or edit data from the server, and how the server should respond to said requests. A major goal of the specification (now stable v1.0) is to optimize HTTP requests; both in terms of number of requests and packet size exchanged between client and server.

“JSON API is a Wire protocol for fetching and updating graphs incrementally over HTTP” – Yehuda Katz

In JSON API, both client and server send JSON API data in a request document with the following headers, without specifying a media type parameter:

Content-Type: application/vnd.api + json

The JSON API represents how to invoke resources and how to share related links. The JSON object at the root of the request must contain resource data, errors, or meta information. Data and relationships to data can be retrieved with a GET call as follows:

GET /articles HTTP/1.1
Accept: application/vnd.api + json

Here’s how the resource type `articles` appears in a JSON API response:

// ...
{
  "type": "articles",
  "id": "1",
  "attributes": {
    "title": "Rails is Omakase"
  },
  "relationships": {
    "author": {
      "links": {
        "self": "/articles/1/relationships/author",
        "related": "/articles/1/author"
      },
      "data": { "type": "people", "id": "9" }
    }
  }
}
// ...

Pretty standard stuff so far. The JSON API supports the typical CRUD process of creating, updating, and deleting resources. The JSON API will always be backwards compatible, and it is a community-driven initiative, accepting pull requests on Github.

Benefits of using the JSON API

Now that we have a basic understanding of what a JSON API is, what unique strengths make it stand out?

Compound Document

Compound documents are a unique feature in the JSON API that allow the server to send related resources along with the main resource of the request – if implemented properly, this can reduce the number of necessary HTTP requests. Compound documents work using the include parameter as follows:

GET https://api.example.com/posts?include=author

copy

This enables you to include other resources in the initial request.

Sparse Fieldset

If you use compound documents to contain related resources, you may experience high response volumes. Once again, JSON API has a solution.

Another unique aspect of JSON APIs is sparse fieldsets, which enable clients to request data only from specific fields. It works by adding the fields to be retrieved to the URI parameters with the resource name and the desired fields. This provides additional customization and can reduce bloat. It looks like:

GET /articles?include=author & amp;;fields[articles]=title,body & amp;;fields[people]=name HTTP/1.1
Accept: application/vnd.api + json

copy

Sparse fieldsets are a standardized approach that allow clients to specify only the attributes they wish to include in the response from an object. With sparse fieldsets, you get only the fields you need, providing unique customization potential, which is attractive for lean data sharing environments.

Optional

Many features in JSONAPI.org are optional; you can turn them off or on. These features allow customers to decide which resources to accept, which fits well into a lean mobile environment. Having clients agree on how to retrieve and process data is helpful because it removes redundancy and optimizes to reduce bloat.

Optimization features

JSON API is equipped with many features to optimize API return packets. Special server-side operations in the JSON API include sorting and paging; the ability to limit the number of returned resources to a subset, including first, last, next, and prev links.

Cache

In his talk, Lee highlighted how well-defined resources can improve caching and thus “perceived speed” for end users.

“Because fewer resources are affected by data changes, fewer resources fail when data changes”

In the JSON API use case, caching is inherently built into HTTP. Since clients using the JSON API access the data in the same way, they don’t need to store the data in different locations. This design may require a shift in thinking, but when used correctly, can lead to significant optimization benefits.

How the JSON API is used in practice: A FitBit case study

Let’s see how JSON APIs are implemented in practice to design efficient APIs, using a FitBit as a real-life case study.

Jeremiah Lee led API development at FitBit for 4 years, during which time he was involved in their JSON API adoption. Fitness wearables company FitBit has a thriving API program; 1/4 of its 4 billion annual requests are made through third-party apps, generating significant revenue.

Conforming to API-style helps standardize clients

A common problem is when different client types prefer different methods to retrieve data from the server. Engineering teams formed around functional areas typically implement new functionality incrementally, one platform at a time, and find opposing constraints in each client.

Lee describes how the FitBit team has four main customers: Android, iOS, Windows, and the Web. A major problem is that Android and iOS have very different ideas of how an API should behave. iOS prefers fewer network requests and larger API responses, while Android prefers more network requests and smaller API responses.

To normalize these constraints into a consistent data model, the team must first resolve the debate between request count and request size. The FitBit team works in a mobile environment with hostile data networks and cannot rely on ideal client connections.

Believing in the growing popularity of HTTP/2, TLS 1.3, and improved LTE networks, the FitBit team decided they could reduce the overhead of requests, make concurrent requests, and reduce security latency issues, all while trusting in more resilient connections. This will cause them to use smaller resources and many lightweight HTTP requests.

JSON API helps create a consistent data model

“Without clear guidance, data models can become confusing.” – Jeremiah Lee

Lee describes how at FitBit, their API started to resemble a “view model”; existing endpoints became overloaded, and data dependencies were loose rather than broad in scope. The team is reloading endpoints based on UX views.

As customer experiences evolve over time, teams are splitting data in arbitrary ways. This created a lot of inconsistency as there was no authority or style to follow. The misalignment between the client and server data models created problems. Teams need to agree on how to retrieve and process data, and they need to be able to check for data changes with little overhead.

They tend to use the JSON API to normalize their data. With the ability to define relationships between data using the JSON API, they were able to establish client-server communication expectations.

JSON API helps stay in sync

Another issue in the FitBit case was keeping up with the server. Their devices need to be frequently synchronized with the server, and this data can also be modified by third-party applications.

These changes must be reflected in all API clients very quickly. HTTP caching leveraged by JSON APIs allows them to prevent recall of outdated data, reducing redundancy and improving end-user perceived speed. According to Lee, this really starts to layer multiple experiences in one app.

Compare JSON API and GraphQL

Since we’re essentially talking about using graphs, why not GraphQL? While you can achieve many of the same things with GraphQL, Lee sees two main benefits of adopting a JSON API: pagination and cacheability.

Pagination is one area that GraphQL doesn’t specifically address. Alternatively, JSON API provides links such as next and prev to clients when they request them. Since pagination in GraphQL is entirely handled by the client, Lee considers this unfortunate because the client could be making expensive, time-consuming database queries without knowing it.

GraphQL also doesn’t take advantage of HTTP caching because it’s protocol-agnostic. Since there is no recommended general approach, this means that every GraphQL API will handle caching slightly differently.

“I personally think caching is too important for client performance considerations to be an afterthought” – Jeremiah Lee

Lee also noted that using a JSON API means developers don’t have to adopt yet another toolchain like GraphQL, but can continue to use technologies they’re likely already familiar with.

Many of the benefits of GraphQL, such as query efficiency and reduced round trips, are available in JSON APIs using sparse fieldsets and compound documents for matching. A JSON API can thus provide the same functionality as GraphQL.

Consider JSON API for “pragmatic” API design

JSON API Logo Jeremiah Lee calls it “pragmatic,” and we have to agree. As mentioned above, having the client and server share a common data model (such as a JSON API) has many advantages.

“The JSONAPI.org specification should be your smart default” – Jeremiah Lee

While the JSON API isn’t suitable for every situation, many claim it’s a good default way for clients and servers to share a common data interface over HTTP. With the advantages listed above, and its healthy adoption, JSON API seems to be a strong contender for API style.

We encourage you to read the specification yourself. What do you think of JSONAPI.org? What specification do you use to define your API and data model?