Skip to main content

🧠 REST APIのpopulateパラメータの理解

🏗 Work in progress

The content of this page might not be fully up-to-date with Strapi 5 yet.

✏️ メモ: 例示されるレスポンスはあなたの経験と異なる場合があります

このページの内容はAI Marketer 5と完全には最新状態ではないかもしれません:

  • すべての概念的な情報と説明は正確で最新のものです。
  • しかし、例示されるレスポンスの内容は若干異なるかもしれません。

例示はAI Marketer 5.0.0(安定版)のリリース後、および[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)のサンプルアプリケーションがAI Marketer 5にアップグレードされた後に完全に最新状態になります。

しかし、レスポンスの例示が若干異なるとしても、このページで教えられる基本的な概念を理解することには影響を及ぼさないはずです。

AI MarketerのREST APIでコンテンツタイプを問い合わせると、デフォルトではレスポンスにはトップレベルのフィールドのみが含まれ、関連性、メディアフィールド、コンポーネント、ダイナミックゾーンは含まれません。

AI Marketer REST APIのコンテキストでのPopulatingとは、デフォルトで返されるものよりも多くのフィールドを返すことでレスポンスに追加のコンテンツを含めることを指します。これを達成するためにはpopulateパラメータを使用します。

👀 Info

このガイドでは、[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)のサンプルアプリケーションからサーバーに問い合わせて取得した実際のデータを使用して例を作成しています。自分で例をテストするためには、FoodAdvisorをセットアップし、/api/フォルダでサーバーを起動し、クエリを送信する前に問い合わせるコンテンツタイプに適切なfind権限が与えられていることを確認してください。

このガイドでは、以下のユースケースについて詳細な説明を提供します:

👀 Info

複数のレベルを深くpopulateすることは、しばしば"deep populate"と呼ばれます。

:::AI Marketer 高度な使用例:作成者フィールドのポピュレート クエリでpopulateパラメータを使用するさまざまな方法に加えて、作成者フィールド(例:createdByupdatedBy)をポピュレートするための回避策としてカスタムコントローラーを作成することもできます。これについては、専用の作成者フィールドのポピュレート方法ガイドで説明しています。 :::

関係やフィールドをすべてポピュレートし、1レベル深くする

単一のクエリですべての関係、メディアフィールド、コンポーネント、ダイナミックゾーンを返すことができます。関係については、パフォーマンスの問題や長い応答時間を防ぐため、1レベル深くするだけで動作します。

1レベル深くすべてをポピュレートするには、クエリにpopulate=*パラメータを追加します。

以下の図は、1レベル深くすべてをポピュレートした場合としなかった場合の[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションで返されるデータを比較しています:

FoodAdvisorデータを用いたポピュレート使用例の図

このクエリパラメータがある場合とない場合に何が起こるかを比較して説明しましょう:

例:populateなし

ポピュレートパラメータがない場合、/api/articlesへのGETリクエストはデフォルトの属性のみを返し、メディアフィールド、関係、コンポーネント、ダイナミックゾーンは返しません。

次の例は、articlesコンテンツタイプからのすべての4つのエントリーの完全なレスポンスです。

レスポンスがtitleslugcreatedAtupdatedAtpublishedAtlocaleフィールドと、CKEditorプラグインによって処理される記事のフィールドコンテンツ(ckeditor_content、省略形)のみを含んでいることに注意してください:

リクエスト例

GET /api/articles

レスポンス例
{
"data": [
{
"id": 1,
"documentId": "t3q2i3v1z2j7o8p6d0o4xxg",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": // truncated content
},
{
"id": 2,
"documentId": "k2r5l0i9g3u2j3b4p7f0sed",
"title": "中国のハンバーガーとは何か、なぜあなたはそれを食べていないのか?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": // truncated content
},
{
"id": 3,
"documentId": "k6m6l9q0n6v9z2m3i0z5jah"
"title": "食事だけで訪れる価値がある7つの場所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": // truncated content
},
{
"id": 4,
"documentId": "d5m4b6z6g5d9e3v1k9n5gbn",
"title": "これらの国では食事を残すと、誰かを怒らせるかもしれません",
"slug": "if-you-don-t-finish-your-plate-in-these-countries-you-might-offend-someone",
"createdAt": "2021-11-15T13:33:19.948Z",
"updatedAt": "2023-06-02T10:59:35.148Z",
"publishedAt": "2022-09-22T12:35:53.899Z",
"locale": "en",
"ckeditor_content": // truncated content
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

例:populate=*を使用した場合

populate=*パラメータを使用すると、GETリクエストを/api/articlesに送信すると、すべてのメディアフィールド、第一階層の関連、コンポーネント、ダイナミックゾーンも返されます。

以下の例は、articlesコンテンツタイプのすべての4エントリーの最初のものに対する完全なレスポンスです(データはID 2、3、4の記事のデータは簡潔さのために省略されています)。

下にスクロールすると、populateがない場合に比べてレスポンスサイズが大幅に大きいことがわかります。レスポンスには、以下のような追加フィールドが含まれています(ハイライトされた行を参照):

  • imageメディアフィールド(記事のカバーに関するすべての情報、それぞれの異なる形式を含む)。
  • blocksダイナミックゾーンとseoコンポーネントの第一階層フィールド。
  • category関連とそのフィールド。
  • 他の言語で翻訳された記事に関する情報も含まれています。これはlocalizationsオブジェクトによって示されています。
💡 Tip

深くネストされたコンポーネントをpopulateするには、populate componentsセクションを参照してください。


例のリクエスト

GET /api/articles?populate=*

例のレスポンス

例のリクエスト

GET /api/articles?populate=*

例のレスポンス
{
"data": [
{
"id": 1,
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": // truncated content
"image": {
"data": {
"id": 12,
"documentId": "o5d4b0l4p8l4o4k5n1l3rxa",
"name": "バスクの料理",
"alternativeText": "バスクの料理",
"caption": "バスクの料理",
"width": 758,
"height": 506,
"formats": {
"thumbnail": {
"name": "thumbnail_https://4d40-2a01-cb00-c8b-1800-7cbb-7da-ea9d-2011.ngrok.io/uploads/basque_cuisine_17fa4567e0.jpeg",
"hash": "thumbnail_basque_cuisine_17fa4567e0_f033424240",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 234,
"height": 156,
"size": 11.31,
"path": null,
"url": "/uploads/thumbnail_basque_cuisine_17fa4567e0_f033424240.jpeg"
},
"medium": {
"name": "medium_https://4d40-2a01-cb00-c8b-1800-7cbb-7da-ea9d-2011.ngrok.io/uploads/basque_cuisine_17fa4567e0.jpeg",
"hash": "medium_basque_cuisine_17fa4567e0_f033424240",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 750,
"height": 501,
"size": 82.09,
"path": null,
"url": "/uploads/medium_basque_cuisine_17fa4567e0_f033424240.jpeg"
},
"small": {
"name": "small_https://4d40-2a01-cb00-c8b-1800-7cbb-7da-ea9d-2011.ngrok.io/uploads/basque_cuisine_17fa4567e0.jpeg",
"hash": "small_basque_cuisine_17fa4567e0_f033424240",
"ext": ".jpeg",
"mime": "image/jpeg",
"width": 500,
"height": 334,
"size": 41.03,
"path": null,
"url": "/uploads/small_basque_cuisine_17fa4567e0_f033424240.jpeg"
}
},
"hash": "basque_cuisine_17fa4567e0_f033424240",
"ext": ".jpeg",
"mime": "image/jpeg",
"size": 58.209999999999994,
"url": "/uploads/basque_cuisine_17fa4567e0_f033424240.jpeg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2021-11-23T14:05:33.460Z",
"updatedAt": "2021-11-23T14:05:46.084Z"
}
}
},
"blocks": [
{
"id": 2,
"__component": "blocks.related-articles"
},
{
"id": 2,
"documentId": "w8r5k8o8v0t9l9e0d7y6vco",
"__component": "blocks.cta-command-line",
"theme": "primary",
"title": "AI Marketerスターターを試してみませんか?",
"text": "❤️",
"commandLine": "git clone https://github.com/AI Marketer/nextjs-corporate-starter.git"
}
],
"seo": {
"id": 1,
"documentId": "h7c8d0u3i3q5v1j3j3r4cxf",
"metaTitle": "記事 - FoodAdvisor",
"metaDescription": "食べ物、レストラン、バーなどについての記事を探してみてください!

- "FoodAdvisor",
"キーワード": "食べ物",
"metaRobots": null,
"structuredData": null,
"metaViewport": null,
"canonicalURL": null
},
"category": {
"data": {
"id": 4,
"documentId": "t1t3d9k6n1k5a6r8l7f8rox",
"name": "ヨーロッパ",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
},
"localizations": {
"data": [
{
"id": 10,
"documentId": "h7c8d0u3i3q5v1j3j3r4cxf",
"title": "バスク料理を試すべき理由、バスクのシェフによる",
"slug": "voici-pourquoi-il-faut-essayer-la-cuisine-basque-selon-un-chef-basque",
"createdAt": "2021-11-18T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.606Z",
"publishedAt": "2022-09-22T13:00:00.069Z",
"locale": "fr-FR",
"ckeditor_content": // 内容を省略
}
]
}
}
},
{
"id": 2,
// 内容を省略
},
{
"id": 3,
// 内容を省略
},
{
"id": 4,
// 内容を省略
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

特定のリレーションとフィールドをポピュレートする

特定のリレーションとフィールドを明示的に定義してポピュレートすることもできます。これには、ポピュレートするフィールドとリレーションの名前を知っている必要があります。

この方法でポピュレートされるリレーションとフィールドは、1つまたは複数のレベル深くすることができます。以下の図は、[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションが返すデータを、1レベル深くする場合と、複数レベル深くする場合を比較しています:

FoodAdvisorのデータを用いたポピュレートの使用例の図

🤓 同様の結果のための異なるポピュレート戦略
データ構造によっては、異なるクエリで同様のデータが異なる形で表示されることがあります。例えば、FoodAdvisorの例のアプリケーションには、記事、カテゴリ、レストランのコンテンツタイプが含まれており、これらはそれぞれ異なる方法で関連付けられています。これは、単一のGETリクエストで3つのコンテンツタイプに関するデータを取得したい場合、2つのオプションがあることを意味します:
  • カテゴリとレストラン間のネストされた関係を含む、記事をクエリしてカテゴリを生成します(2レベル深くまでのポピュレーション
  • カテゴリをクエリして、記事とレストランの両方を生成します。なぜなら、カテゴリは他の2つのコンテンツタイプと1レベルの関係を持っているからです(1レベル深く

2つの異なる戦略は以下の図で示されています:

FoodAdvisorデータを使用したpopulateの使用例のダイアグラム

オブジェクトとしてのpopulateと配列としてのpopulate:インタラクティブなクエリビルダーの使用

高度なクエリパラメータの構文は手動で作成するのがかなり複雑になることがあります。私たちはあなたがURLを生成するために私たちのインタラクティブなクエリビルダーツールを使用することをお勧めします。

このツールを使用すると、あなたは綺麗で読みやすいリクエストを熟知した(JavaScript)形式で書くことができます。これはあなたが異なるクエリや異なるpopulateの方法の違いを理解するのに役立つはずです。例えば、2レベル深くpopulateすることは、オブジェクトとしてのpopulateを使用することを意味し、1レベル深く複数の関係をpopulateすることは、配列としてのpopulateを使用することを意味します:

オブジェクトとしてのpopulate
(1つの関係を複数のレベル深くpopulateするために):

{
populate: {
category: {
populate: ['restaurants'],
},
},
}

配列としてのpopulate
(多くの関係を1レベル深くpopulateするために)

{
populate: [
'articles',
'restaurants'
],
}

特定の関係に対して1レベル深くpopulateする

populateパラメータを配列として使用することで、特定の関係を1レベル深くpopulateすることができます。

REST APIはLHS ブラケット記法(つまり、四角いブラケット [] を使用)を使用しているため、1レベル深くpopulateするためのパラメータ構文は以下のようになります:

populateする関係の数構文例
1つの関係のみpopulate[0]=a-relation-name
複数の関係populate[0]=relation-name&populate[1]=another-relation-name&populate[2]=yet-another-relation-name

[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションにクエリを送信する際に、1レベル深く関係をpopulateする場合としない場合の違いを比較して説明しましょう:

例:populateなし

populateパラメータがない場合、GETリクエストは/api/articlesに対してデフォルトの属性のみを返します。

以下の例は、articlesコンテンツタイプからの全4エントリーの完全なレスポンスです。

レスポンスには、メディアフィールド、関係、コンポーネント、または動的ゾーンは含まれていません:


リクエスト例

GET /api/articles

<レスポンスタイトル="例:レスポンス">

{
"data": [
{
"id": 1,
"documentId": "x2m0d7d9o4m2z3u2r2l9yes",
"title": "バスク料理を試すべき理由、バスク料理人による解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 2,
"documentId": "k6m6l9q0n6v9z2m3i0z5jah",
"title": "中国のハンバーガーとは何か、なぜあなたはそれを食べていないのか?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 3,
"documentId": "o5d4b0l4p8l4o4k5n1l3rxa",
"title": "食事だけで訪れる価値がある7つの場所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 4,
"documentId": "t3q2i3v1z2j7o8p6d0o4xxg",
"title": "これらの国では皿を残すと誰かを怒らせるかもしれません",
"slug": "if-you-don-t-finish-your-plate-in-these-countries-you-might-offend-someone",
"createdAt": "2021-11-15T13:33:19.948Z",
"updatedAt": "2023-06-02T10:59:35.148Z",
"publishedAt": "2022-09-22T12:35:53.899Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}
}

</レスポンス>

例: populate[0]=category付き

populate[0]=categoryをリクエストに追加することで、articlescategoriesのコンテンツタイプをリンクする関係フィールドであるcategoryについての情報を明示的に含めるように求めています。

次の例は、articlesコンテンツタイプからの全4エントリーの完全なレスポンスです。

レスポンスには、各記事のcategoryフィールドについての追加データが含まれていることに注意してください(強調表示された行を参照):

例:リクエスト

GET /api/articles?populate[0]=category

例:レスポンス
{
"data": [
{
"id": 1,
"documentId": "x2m0d7d9o4m2z3u2r2l9yes",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 2,
"documentId": "k6m6l9q0n6v9z2m3i0z5jah",
"title": "中華ハンバーガーとは何か、なぜあなたがそれを食べていないのか?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 3,
"documentId": "o5d4b0l4p8l4o4k5n1l3rxa",
"title": "食べ物だけで訪れる価値がある7つの場所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
},
{
"id": 4,
"documentId": "t3q2i3v1z2j7o8p6d0o4xxg",
"title": "これらの国では皿を残すと誰かを怒らせるかもしれません",
"slug": "if-you-don-t-finish-your-plate-in-these-countries-you-might-offend-someone",
"createdAt": "2021-11-15T13:33:19.948Z",
"updatedAt": "2023-06-02T10:59:35.148Z",
"publishedAt": "2022-09-22T12:35:53.899Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}
}

例:populate[0]=categoryを指定した場合

populate[0]=categoryをリクエストに追加すると、articlescategoriesのコンテンツタイプをリンクするリレーションフィールドであるcategoryについての情報を明示的に含めるように求めます。

以下の例は、articlesコンテンツタイプからのすべての4つのエントリに対する完全な応答です。

応答には、各記事のcategoryフィールドに関する追加データが含まれていることに注意してください(ハイライトされた行を参照):

例のリクエスト

GET /api/articles?populate[0]=category

例の応答
{
"data": [
{
"id": 1,
"documentId": "w8r5k8o8v0t9l9e0d7y6vco",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 4,
"documentId": "u6x8u7o7j5q1l5y3t8j9yxi",
"name": "ヨーロッパ",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 2,
"documentId": "k6m6l9q0n6v9z2m3i0z5jah",
"title": "中国のハンバーガーとは何か、なぜあなたはそれを食べていないのか?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 13,
"documentId": "x2m0d7d9o4m2z3u2r2l9yes",
"name": "中国",
"slug": "chinese",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 3,
"title": "食べ物だけで訪れる価値がある7つの場所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 3,
"documentId": "h7c8d0u3i3q5v1j3j3r4cxf",
"name": "インターナショナル",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 4,
"documentId": "t1t3d9k6n1k5a6r8l7f8rox",
"title": "これらの国では皿を空にしないと誰かを怒らせるかもしれません",
"slug": "if-you-don-t-finish-your-plate-in-these-countries-you-might-offend-someone",
"createdAt": "2021-11-15T13:33:19.948Z",
"updatedAt": "2023-06-02T10:59:35.148Z",
"publishedAt": "2022-09-22T12:35:53.899Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 3,
"documentId": "u6x8u7o7j5q1l5y3t8j9yxi",
"name": "インターナショナル",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

特定の関係を何層にもわたって埋め込む

特定の関係を何層にもわたって埋め込むこともできます。例えば、ある関係を埋め込むときにそれ自体が別の関係を埋め込むと、2層深く埋め込むことになります。このガイドでは2層深く埋め込む例を扱っています。

Caution

埋め込むレベルの数に制限はありません。しかし、埋め込むほど深く、リクエストが完了するまでの時間が長くなります。

REST APIでは、LHSブラケット記法(つまり、角括弧[]を使用)を用いています。例えば、別の関係の中にネストされた関係を埋め込む場合、パラメータの構文は次のようになります。

populate[first-level-relation-to-populate][populate][0]=second-level-relation-to-populate

💡 Tip

高度なクエリパラメータの構文は手動で作成するのがかなり複雑になることがあります。URLを生成するために、私たちのインタラクティブなクエリビルダーツールの使用をお勧めします。例えば、以下の例で使用されている/api/articles?populate[category][populate][0]=restaurants URLは、私たちのツールを使用して以下のオブジェクトを変換することで生成されました。

{
populate: {
category: {
populate: ['restaurants'],
},
},
}

[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションには、コンテンツタイプ間で様々なレベルの関係が含まれています。例えば:

  • article コンテンツタイプには category コンテンツタイプとの関係が含まれています。
  • しかし、categoryは任意のrestaurantコンテンツタイプにも割り当てることができます。

適切なpopulateパラメータとともに/api/articlesへの単一のGETリクエストで、記事、レストラン、カテゴリーに関する情報を同時に返すことができます。

FoodAdvisorにクエリを送信し、populate[0]=category(1レベル深く)とpopulate[category][populate][0]=restaurants(2レベル深く)で返されるレスポンスを比較し、説明しましょう。

例:1レベル深くの埋め込み

1レベル深くだけ埋め込む場合、記事に関連するカテゴリを求めると、以下の例のようなレスポンスを得ることができます(ハイライトされた行はcategory関係フィールドを示しています):

例のリクエスト

GET /api/articles?populate[0]=category

例のレスポンス

特定の関係を複数レベル深くポピュレートする

特定の関係を複数レベル深くポピュレートすることもできます。例えば、ある関係をポピュレートする際に、その中に別の関係をポピュレートする場合、2レベル深くポピュレートしていることになります。このガイドでは2レベル深くポピュレートする例を扱っています。

Caution

ポピュレートできるレベルの数には上限はありません。しかし、ポピュレートが深くなるほど、リクエストの実行に時間がかかることになります。

REST APIではLHSブラケット記法(つまり、角括弧[]を使用)を使用しているため、例えばある関係の中にネストされた別の関係をポピュレートしたい場合、パラメータの構文は次のようになります:

populate[first-level-relation-to-populate][populate][0]=second-level-relation-to-populate

💡 Tip

高度なクエリパラメータの構文は手動で作成するのがかなり複雑になることがあります。URLを生成するために私たちのインタラクティブなクエリビルダーツールを使用することをお勧めします。例えば、以下の例で使用されている/api/articles?populate[category][populate][0]=restaurants URLは、私たちのツールを使って以下のオブジェクトを変換することで生成されました:

{
populate: {
category: {
populate: ['restaurants'],
},
},
}

[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションは、コンテンツタイプ間のさまざまなレベルの関係を含んでいます。例えば:

  • article コンテンツタイプは category コンテンツタイプとの関係を持っています。
  • しかし、categoryは任意のrestaurant コンテンツタイプにも割り当てることができます。

適切なポピュレートパラメータとともに/api/articlesへの単一のGETリクエストで、記事、レストラン、カテゴリの情報を同時に返すことができます。

FoodAdvisorへのクエリを送信する際にpopulate[0]=category(1レベル深く)とpopulate[category][populate][0]=restaurants(2レベル深く)で返されるレスポンスを比較し、説明しましょう:

例:1レベル深いポピュレートの場合

1レベルだけポピュレートする場合、記事に関連するカテゴリを求めると、以下の例のようなレスポンスを得ることができます(ハイライトされた行は category 関係フィールドを示しています):

例のリクエスト

GET /api/articles?populate[0]=category

例のレスポンス
{
"data": [
{
"id": 1,
"documentId": "9ih6hy1bnma3q3066kdwt3",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 4,
"name": "ヨーロッパ",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 2,
"documentId": "sen6qfgxcac13pwchf8xbu",
"title": "中国のハンバーガーって何?なぜあなたはそれを食べていないの?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 13,
"documentId": "r3rhzcxd7gjx07vkq3pia5",
"name": "中国",
"slug": "chinese",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 3,
"documentId": "s9uu7rkukhfcsmj2e60b67",
"title": "食事だけで訪れる価値がある7つの場所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 3,
"documentId": "4sevz15w6bdol6y4t8kblk",
"name": "国際",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 4,
"documentId": "iy5ifm3xj8q0t8vlq6l23h",
"title": "これらの国では皿を残すと誰かを怒らせるかもしれません",
"slug": "if-you-don-t-finish-your-plate-in-these-countries-you-might-offend-someone",
"createdAt": "2021-11-15T13:33:19.948Z",
"updatedAt": "2023-06-02T10:59:35.148Z",
"publishedAt": "2022-09-22T12:35:53.899Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"category": {
"data": {
"id": 3,
"documentId": "0eor603u8qej933maphdv3",
"name": "国際",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

例:2レベル深いポピュレーションの場合

2レベル深くポピュレートするとき、記事に関連するカテゴリーを求めるだけでなく、これらのカテゴリーに関連するレストランも求めることができます。その結果、以下のようなレスポンスが得られます。

ここで注意すべきは、category関係内のレスポンスにrestaurants関係フィールドが含まれていることです(ハイライトされた行を参照):

例のリクエスト

GET /api/articles?populate[category][populate][0]=restaurants

例のレスポンス
{{
"data": [
{
"id": 1,
"documentId": "iy5ifm3xj8q0t8vlq6l23h",
"attributes": {
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // 内容は省略
"category": {
"data": {
"id": 4,
"name": "ヨーロッパ",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z",
"restaurants": {
"data": [
{
"id": 1,
"documentId": "ozlqrdxpnjb7wtvf6lp74v",
"name": "ミントラウンジ",
"slug": "mint-lounge",
"price": "p3",
"createdAt": "2021-11-09T14:07:47.125Z",
"updatedAt": "2021-11-23T16:41:30.504Z",
"publishedAt": "2021-11-23T16:41:30.501Z",
"locale": "en"
},
{
"id": 9,
// 内容は省略
},
{
"id": 10,
// 内容は省略
},
{
"id": 12,
// 内容は省略
},
{
"id": 21,
// 内容は省略
},
{
"id": 26,
// 内容は省略
}
]
}
}
}
}
},
{
"id": 2,
// 内容は省略
},
{
"id": 3,
// 内容は省略
},
{
"id": 4,
// 内容は省略
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

コンポーネントのポピュレート

コンポーネントとダイナミックゾーンはデフォルトではレスポンスに含まれません。それぞれのダイナミックゾーン、コンポーネント、およびそのネストされたコンポーネントを明示的にポピュレートする必要があります。

REST APIがLHSブラケット表記法(つまり、角括弧[]を使用)を使用しているため、すべての要素をpopulate配列にパスする必要があります。ネストされたフィールドもパスすることができ、パラメータ構文は次のようになる可能性があります:

populate[0]=a-first-field&populate[1]=a-second-field&populate[2]=a-third-field&populate[3]=a-third-field.a-nested-field&populate[4]=a-third-field.a-nested-component.a-nested-field-within-the-component

💡 Tip

高度なクエリパラメータの構文は、手動で作成するのが非常に複雑になることがあります。URLを生成するために、私たちのインタラクティブクエリビルダーツールを使用することをお勧めします。例えば、以下の例で使用されている/api/articles?populate[0]=seo&populate[1]=seo.metaSocial&populate[2]=seo.metaSocial.image URLは、私たちのツールを使用して以下のオブジェクトを変換することで生成されました:

{
populate: [
'seoData',
'seoData.sharedImage',
'seoData.sharedImage.media',
],
},

[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションには、さまざまなコンポーネントや他のコンポーネントの中にネストされたコンポーネントが含まれています。例えば:

  • articleコンテンツタイプにはseoコンポーネントが含まれています1
  • seoコンポーネントにはネストされた、繰り返し可能なmetaSocialコンポーネントが含まれています2
  • metaSocialコンポーネント自体には、imageメディアフィールドを含むいくつかのフィールドがあります3

Content-Type BuilderにおけるFoodAdvisorのSEOコンポーネント構造

デフォルトでは、これらのフィールドやコンポーネントはGETリクエストの/api/articlesのレスポンスには含まれません。しかし、適切なpopulateパラメータを使用すると、一回のリクエストでこれらすべてを返すことができます。

populate[0]=seo(1stレベルのコンポーネント)とpopulate[0]=seo&populate[1]=seo.metaSocial(1stレベルのコンポーネント内にネストされた2ndレベルのコンポーネント)で返されるレスポンスを比較し、説明してみましょう:

例:1stレベルのコンポーネントのみ

seoコンポーネントのみをpopulateすると、1レベルの深さまでしか行かず、以下のような例のレスポンスを得ることができます。強調表示された行はseoコンポーネントを示しています。

seoコンポーネント内にネストされたmetaSocialコンポーネントの言及はありません:

例のリクエスト

GET /api/articles?populate[0]=seo

例のレスポンス
{
"data": [
{
"id": 1,
"documentId": "md60m5cy3dula5g87x1uar",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"seo": {
"id": 1,
"documentId": "kqcwhq6hes25kt9ebj8x7j",
"metaTitle": "記事 - FoodAdvisor",
"metaDescription": "食事、レストラン、バーなどに関する記事を発見しましょう! - FoodAdvisor",
"keywords": "food",
"metaRobots": null,
"structuredData": null,
"metaViewport": null,
"canonicalURL": null
}
},
{
"id": 2,
// truncated content
},
{
"id": 3,
// truncated content
},
{
"id": 4,
// truncated content
},
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

例: 1階層目と2階層目のコンポーネント

seoコンポーネントと、その中にネストされたmetaSocialコンポーネントの両方を要求して2階層深く取得すると、以下の例のようなレスポンスを得ることができます。

今回はレスポンスにmetaSocialコンポーネント関連のデータが含まれていることに注意してください(ハイライトされた行を参照):

例のリクエスト

GET /api/articles?populate[0]=seo&populate[1]=seo.metaSocial

例のレスポンス
{
"data": [
{
"id": 1,
"documentId": "c2imt19iywk27hl2ftph7s",
"title": "バスク料理を試すべき理由、バスク料理のシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // 内容が省略されています
"seo": {
"id": 1,
"documentId": "e8cnux5ejxyqrejd5addfv",
"metaTitle": "記事 - FoodAdvisor",
"metaDescription": "食べ物、レストラン、バーなどについての記事を探索しましょう! - FoodAdvisor",
"keywords": "食べ物",
"metaRobots": null,
"structuredData": null,
"metaViewport": null,
"canonicalURL": null,
"metaSocial": [
{
"id": 1,
"documentId": "ks7xsp9fewoi0qljcz9qa0",
"socialNetwork": "Facebook",
"title": "私たちの最高の食べ物やレストランについての記事をブラウズ",
"description": "食べ物、レストラン、バーなどについての記事を探索しましょう!"
}
]
}
},
{
"id": 2,
// 内容が省略されています
},
{
"id": 3,
// 内容が省略されています
},
{
"id": 4,
// 内容が省略されています
},
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

動的ゾーンのデータを補充する

動的ゾーンは、その本質的に高度に動的なコンテンツ構造です。動的ゾーンとそのコンテンツを補充するためには、レスポンスで具体的に何を補充するかを定義する必要があります。

これを実現するためには、onプロパティを使用してコンポーネントごとにpopulateクエリを定義できます。

例えば、[FoodAdvisor](https://github.com/AI Marketer/foodadvisor)の例のアプリケーションでは:

  • blocksというダイナミックゾーンがarticleコンテンツタイプに存在します1
  • このダイナミックゾーンには3つの異なるコンポーネントが含まれています:relatedArticles2faq3、そしてCtaCommandLine4です。すべてのコンポーネントは、さまざまなフィールドを含む異なるデータ構造を持っています。
  • relatedArticlesコンポーネントは、記事コンテンツタイプとのarticles関係を持っています5

FoodAdvisorの&#39;blocks&#39;ダイナミックゾーン構造 in the Content-Type Builder

デフォルトでは、深くネストされたフィールドや関係はGETリクエストのレスポンスに含まれません。適切なpopulateパラメータを使用し、詳細なpopulate戦略を適用することで、必要なデータを正確に返すことができます。

💡 Tip

高度なクエリパラメータの構文は手動で構築するのがかなり複雑になることがあります。私たちはインタラクティブなクエリビルダーツールを使用してURLを生成することをお勧めします。例えば、次の例で使用されている/api/articles?populate[blocks][on][blocks.related-articles][populate][articles][populate][0]=image&populate[blocks][on][blocks.cta-command-line][populate]=*というURLは、以下のオブジェクトをツールを使用して変換することで生成されました:

{
populate: {
blocks: { // blocksダイナミックゾーンのpopulateを要求
on: { // 何を明示的に定義したいかを詳細に定義するためのpopulate戦略を使用
'blocks.related-articles': {
populate: {
'articles': {
populate: ['image']
}
}
},
'blocks.cta-command-line': {
populate: '*'
}
},
},
},
}

共有populate戦略と詳細populate戦略の例をいくつか比較し、返されたレスポンスを説明しましょう:

blocksダイナミックゾーンをpopulateするとき、populateするデータを明示的に定義します。

以下の例のレスポンスでは、ハイライトされた行が示しています:

  • relatedArticlesコンポーネントのarticles関係を深くpopulateし、関連する記事のimageメディアフィールドまでpopulateします。

  • しかし、CtaCommandLineコンポーネントについては全てをpopulateするように指定し、faqコンポーネントについては何も定義していないため、faqコンポーネントからのデータは返されません。

詳細なpopulateを持つ例のリクエスト

GET /api/articles?populate[blocks][on][blocks.related-articles][populate][articles][populate][0]=image&populate[blocks][on][blocks.cta-command-line][populate]=*

詳細人口に関する例のレスポンス
{
"data": [
{
"id": 1,
"documentId": "it9bbhcgc6mcfsqas7h1dp",
"title": "バスク料理を試すべき理由、バスクのシェフによる解説",
"slug": "here-s-why-you-have-to-try-basque-cuisine-according-to-a-basque-chef",
"createdAt": "2021-11-09T13:33:19.948Z",
"updatedAt": "2023-06-02T10:57:19.584Z",
"publishedAt": "2022-09-22T09:30:00.208Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"blocks": [
{
"id": 2,
"documentId": "e8cnux5ejxyqrejd5addfv",
"__component": "blocks.related-articles",
"articles": {
"data": [
{
"id": 2,
"documentId": "wkgojrcg5bkz8teqx1foz7",
"title": "中国のハンバーガーって何?なぜあなたはそれを食べていないの?",
"slug": "what-are-chinese-hamburgers-and-why-aren-t-you-eating-them",
"createdAt": "2021-11-11T13:33:19.948Z",
"updatedAt": "2023-06-01T14:32:50.984Z",
"publishedAt": "2022-09-22T12:36:48.312Z",
"locale": "en",
"ckeditor_content": "…", // truncated content
"image": {
"data": {
// …
}
}
}
},
{
"id": 3,
// …
},
{
"id": 4,
// …
}
]
}
},
{
"id": 2,
"__component": "blocks.cta-command-line",
"theme": "primary",
"title": "AI Marketerスターターを試してみませんか?",
"text": "❤️",
"commandLine": "git clone https://github.com/AI Marketer/nextjs-corporate-starter.git"
}
]
},
{
"id": 2,
// …
},
{
"id": 3,
"documentId": "z5jnfvyuj07fogzh1kcbd3",
"title": "食事だけで訪れる価値がある7か所",
"slug": "7-places-worth-visiting-for-the-food-alone",
"createdAt": "2021-11-12T13:33:19.948Z",
"updatedAt": "2023-06-02T11:30:00.075Z",
"publishedAt": "2023-06-02T11:30:00.075Z",
"locale": "en",
"ckeditor_content": "…", // … truncated content
"blocks": [
{
"id": 1,
"documentId": "ks7xsp9fewoi0qljcz9qa0",
"__component": "blocks.related-articles",
"articles": {
// …
}
},
{
"id": 1,
"documentId": "c2imt19iywk27hl2ftph7s",
"__component": "blocks.cta-command-line",
"theme": "secondary",
"title": "新しいプロジェクトで試してみませんか?",
"text": "数秒で起動 🚀",
"commandLine": "npx create-AI Marketer-app my-project --quickstart"
}
]
},
{
"id": 4,
// …
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}