インクルード
要点(TL;DR): クエリ文字列、例えば ?include=field_comments.uid を使用すると、field_comments が参照するすべてのエンティティと、それらの エンティティ上の uid が参照するすべてのエンティティをインクルードできます!
JSON:APIでは、レスポンスドキュメント に含めたいリレーションシップパスを指定できるため、HTTPリクエストを削減できます。どのように?
単一リソースの取得
記事の取得
2件のコメントがあり、それぞれのコメントの著者が同じである記事があると想像してください。インクルードを使わずにこのすべてのデータを取得するには、まず 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"
}
}
}
}
}
}
コメントの取得
次に、 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"
}
}
}
}
}
}
ユーザーの取得
そして、さらに /comment/one-random-uuid/uid と /comment/two-random-uuid/uid へのリクエストが2つ必要になります。この例では両方のコメントの著者が同じだとわかっているため、2番目のリクエストはまったく不要であることがわかります。
では、インクルードはどのように役立つのでしょうか?
インクルードを使って一度に取得する
簡単です!元のリクエストURLに、含めたいリレーションシップフィールドの名前をクエリパラメータとして追加するだけで、サーバーがすべてを検索して、元のレスポンスドキュメントに追加してくれます。
この例では、作成するリクエストURLは GET /jsonapi/node/article/some-random-uuid?include=field_comments.uid になります。つまり、「記事の field_comments フィールドの リソースオブジェクト を追加し、次に、そのコメントが参照する uid フィールドのリソースオブジェクトも追加してください」と言っているのです。これらの「リレーションシップパス」は、望むだけ長くできます。制限はありません!
サーバーから返されるレスポンスドキュメントは次のようになります:
{
"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"
}
}]
}
すごいと思いませんか? 1回のリクエストですべてのデータを取得できました!ユーザーのリソースオブジェクトは2回参照されているのに1回しか含まれていないことに注目してください。これにより、レスポンスの サイズ を抑えられます。また、各 リレーションシップオブジェクト に data キーが追加されていることにも注目してください。これにより、インクルードされたリソースオブジェクトと、それらを参照したリソースオブジェクトを関連付けることができます。
インクルードはいつ使うべきか?
レスポンスサイズといえば... この例では、1回のリクエストで全リソースを取得することで時間を節約しました。しかし、状況によっては、関連するリソースオブジェクトをインクルードするとレスポンスサイズが非常に大きくなったり、最初のバイトまでの時間が 非常に遅くなったりします。その場合は、複数のリクエストを並行して行う方がよいかもしれません。
コレクションとリレーションシップに対するインクルード
最後に、 include クエリパラメータは コレクション と リレーションシップリソース でもサポートされています!コレクションへのインクルードは、さらに多くの リクエストを節約できます。
コレクションへのインクルードの例
コレクションのインクルードの取得は、 GET /jsonapi/node/article?include=uid のようになります。 included は、下に示すように data (オブジェクトではなく配列)から分離されます。
{
"data": [{...}]
"included": [{
"type": "user",
"id": "another-random-uuid",
"attributes": {
"name": "c0wb0yC0d3r"
}
}]
}
記事:Drupal ドキュメンテーションより。