Inclusies
TL;DR: Gebruik een querystring zoals ?include=field_comments.uid
om alle entiteiten op te nemen waarnaar wordt verwezen door field_comments
én alle entiteiten waarnaar wordt verwezen door uid
op die entiteiten!
JSON:API helpt je HTTP-verzoeken te elimineren door je toe te staan relatiepaden te specificeren die je wilt laten opnemen in het responsdocument. Hoe werkt dat?
Enkele resources ophalen
Artikel ophalen
Stel dat je een artikel hebt met twee reacties en dat beide reacties dezelfde auteur hebben. Om al deze gegevens zonder includes op te halen, zou je eerst een verzoek doen naar 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"
}
}
}
}
}
}
Reactie ophalen
Daarna zou je een verzoek doen naar 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"
}
}
}
}
}
}
Gebruikers ophalen
En opnieuw zou je nog twee verzoeken moeten doen naar /comment/one-random-uuid/uid
en /comment/two-random-uuid/uid
. We zien dat het tweede verzoek volledig onnodig is, omdat we weten dat de auteur van beide reacties in ons voorbeeld dezelfde is.
Dus, hoe kunnen includes hierbij helpen?
Alles in één keer ophalen met include
Dat is eenvoudig! Door gewoon een queryparameter toe te voegen aan de originele request-URL met de namen van de relatievelden die je wilt opnemen, weet de server dat hij alles voor je moet opzoeken en toevoegen aan het originele responsdocument.
In ons voorbeeld zou de URL-request zijn: GET /jsonapi/node/article/some-random-uuid?include=field_comments.uid
. Met andere woorden, je zegt: "voeg de resource-objecten toe voor het field_comments
-veld op het artikel, en daarna ook de resource-objecten voor het uid
-veld op de reacties waarnaar wordt verwezen." Deze "relatiepaden" kunnen zo lang zijn als je wilt, er is geen limiet!
Het responsdocument dat je van de server terugkrijgt, zou er zo uitzien:
{
"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"
}
}]
}
Is dat niet gaaf? We hebben alle gegevens in één verzoek gekregen! Merk op dat het user-resourceobject slechts één keer is opgenomen, ook al wordt het twee keer verwezen. Dit houdt de grootte van de response laag. Merk ook op dat er nu een data
-sleutel in elk relatieobject staat. Dit laat je de opgenomen resource-objecten correleren met de resource-objecten die ernaar verwezen.
Wanneer include gebruiken?
Over de grootte van de response gesproken... in dit voorbeeld hebben we tijd bespaard door alle resources in één enkel verzoek op te halen. Maar in bepaalde omstandigheden kan het opnemen van gerelateerde resource-objecten de response erg groot maken en/of de time-to-first-byte sterk vertragen. In dat geval kan het beter zijn om meerdere verzoeken parallel te doen.
Include voor collecties en relaties
Tot slot wordt de include
-queryparameter ook ondersteund op collecties en relatieresources! Includes op collecties kunnen je veel meer verzoeken besparen.
Include voor collectievoorbeeld
Includes voor collecties ophalen kan er zo uitzien: GET /jsonapi/node/article?include=uid
. De included
zijn vergelijkbaar gescheiden van de data
(array in plaats van object) zoals hieronder weergegeven.
{
"data": [{...}]
"included": [{
"type": "user",
"id": "another-random-uuid",
"attributes": {
"name": "c0wb0yC0d3r"
}
}]
}
Artikel van Drupal Documentatie.