Includes
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"
}
}]
}
Article from Drupal Documentation.