Includes

Last updated on
13 July 2020

TL;DR: Use a query string like ?include=field_comments.uid to include all the entities referenced by field_comments and all the entities referenced by uid on those entities!


JSON:API helps you eliminate HTTP requests by allowing you to specify relationship paths which you would like to be included in the response document. How?

Fetching single resources

Fetch article

Let's imagine you have an article with two comments and each of those comments have the same author. To get all this data without includes, you would first make a request to GET /jsonapi/node/article/some-random-uuid:

{
  "data": {
    "type": "node--article",
    "id": "some-random-uuid",
    "relationships": {
      "field_comments": {
        "links": {
          "related": {
            "href": "https://my.example.com/node/article/some-random-uuid/field_comments"
          }
        }
      }
    }
  }
}

Fetch comment

Then, you would make a request to GET /node/article/some-random-uuid/field_comments:

{
  "data": [{
    "type": "comment",
    "id": "one-random-uuid",
    "relationships": {
      "uid": {
        "links": {
          "related": {
            "href": "https://my.example.com/comment/one-random-uuid/uid"
          }
        }
      }
    }
  }, {
    "type": "comment",
    "id": "two-random-uuid",
    "relationships": {
      "uid": {
        "links": {
          "related": {
            "href": "https://my.example.com/comment/two-random-uuid/uid"
          }
        }
      }
    }
  }
}

Fetch users

And again, you would need to make two more requests to /comment/one-random-uuid/uid and /comment/two-random-uuid/uid . We can see that the second request is entirely unnecessary because we know that the author of both comments is the same in our example.

So, how can includes help?

Fetch all at once using include

It's easy! Just by adding a query parameter to the original request URL with the names of the relationship fields you would like to include, the server will know to look everything up for you and add it to the original response document.

In our example, the URL request you would make would be GET /jsonapi/node/article/some-random-uuid?include=field_comments.uid. In other words, you're saying "please add the resource objects for the field_comments field on the article, then also add the resource objects for the uid field on whichever comments it references." These "relationship paths" can be as long as you'd like, there's no limit!

The response document that you'd get from the server would be:

{
  "data": {
    "type": "node--article",
    "id": "some-random-uuid",
    "relationships": {
      "field_comments": {
        "data": [{
          "type": "comment",
          "id": "one-random-uuid",
        }, {
          "type": "comment",
          "id": "two-random-uuid",
        }],
        "links": {
          "related": {
            "href": "https://my.example.com/node/article/some-random-uuid/field_comments"
          }
        }
      }
    }
  },
  "included": [{
    "type": "comment",
    "id": "one-random-uuid",
    "relationships": {
      "uid": {
        "data": [{
          "type": "user",
          "id": "another-random-uuid",
        }],
        "links": {
          "related": {
            "href": "https://my.example.com/comment/one-random-uuid/uid"
          }
        }
      }
    }
  }, {
    "type": "comment",
    "id": "another-random-uuid",
    "relationships": {
      "uid": {
        "data": [{
          "type": "user",
          "id": "one-random-uuid",
        }],
        "links": {
          "related": {
            "href": "https://my.example.com/comment/two-random-uuid/uid"
          }
        }
      }
    }
  }, {
    "type": "user",
    "id": "another-random-uuid",
    "attributes": {
      "name": "c0wb0yC0d3r"
    }
  }]
}

Isn't that cool? We got all the data in one request! Notice how the user resource object is only included once, even though it's referenced twice. This keeps the response size down. Also, notice how there is now a data key in each relationship object. That let's you correlate the included resource objects with the resource objects that referenced them.

When to use include?

Speaking of response size... in this example, we saved ourselves time by getting all resources in a single request. However, under certain circumstances, including related resource objects will make the response size quite large and/or make the time-to-first-byte very slow. In that case, it might still be better to make multiple requests in parallel.

Include for collection and relationship

Finally, the include query parameter is supported on collection and relationship resources too! Includes on collections can save you many more requests.

Include for collection example

Fetch includes for collection might look like this GET /jsonapi/node/article?include=uid. The included are similar separated from the data (array instead of object) as shown below.

{
  "data": [{...}]
  "included": [{
    "type": "user",
    "id": "another-random-uuid",
    "attributes": {
      "name": "c0wb0yC0d3r"
    }
  }]
}

Help improve this page

Page status: No known problems

You can: