メインコンテンツまでスキップ

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

🏗 Work in progress

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

メモ: レスポンス例は環境によって異なる場合があります

このページの内容は Strapi 5 と完全に一致していない部分があります。

  • 概念の説明は現行の動作に沿っています。
  • 一方、例に出てくるレスポンスの細部は異なることがあります。

例は Strapi 5.0.0(安定版)リリース後、FoodAdvisor サンプルが Strapi 5 に上がったタイミングで揃える予定です。

レスポンス例が少し違っても、このページで扱う考え方の理解を妨げるものではありません。

Strapi の REST API でコンテンツタイプをクエリすると、既定ではレスポンスにはトップレベルのフィールドだけが含まれ、リレーション、メディア、コンポーネント、ダイナミックゾーンは含まれません。

Strapi の REST API でいうポピュレートは、既定より多くのフィールドを返してレスポンスに追加のコンテンツを含めることです。populate パラメータ で行います。

Info

このガイドの例は、FoodAdvisor サンプルに付属するサーバーから実際に取得したデータを使っています。自分で試す場合は FoodAdvisor をセットアップし、/api/ でサーバーを起動し、クエリするコンテンツタイプに適切な find 権限を付けてからリクエストしてください。

このガイドでは次のユースケースを詳しく説明します。

Info

複数階層のポピュレートは「ディープポピュレート」と呼ばれることがあります。

応用: 作成者フィールドのポピュレート

populate の使い方に加え、カスタムコントローラーで作成者フィールド(createdByupdatedBy など)を返す回避策もあります。手順は 作成者フィールドをポピュレートする を参照してください。

すべてのリレーションとフィールドを 1 階層だけポピュレート

1 回のクエリですべてのリレーション、メディア、コンポーネント、ダイナミックゾーンを返せます。リレーションについてはパフォーマンスとレスポンス時間のため、1 階層だけに限られます。

すべてを 1 階層だけポピュレートするには、クエリに populate=* を付けます。

次の図は、FoodAdvisor サンプルで、すべてを 1 階層ポピュレートした場合とそうでない場合の違いを示しています。

FoodAdvisor データでの populate の違い(図)

このパラメータの有無で何が変わるか見ていきます。

例: populate なし

populate を付けないと、/api/articles への GET は既定の属性だけを返し、メディア、リレーション、コンポーネント、ダイナミックゾーンは含まれません。

次の例は articles コンテンツタイプの 4 件すべてのレスポンスです。

titleslugcreatedAtupdatedAtpublishedAtlocale と、CKEditor プラグインの記事本文(ckeditor_content、ここでは省略)だけが含まれることに注目してください。

リクエスト例

GET /api/articles

レスポンス例
{
"data": [
{
"id": 1,
"documentId": "t3q2i3v1z2j7o8p6d0o4xxg",
"title": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "What are chinese hamburgers and why aren't you eating them?",
"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 Places worth visiting for the food alone",
"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": "If you don't finish your plate in these countries, you might offend someone",
"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=* を付けると、/api/articles への GET はメディア、第 1 階層のリレーション、コンポーネント、ダイナミックゾーンも返します。

次の例は articles の 4 件のうち最初の 1 件の完全なレスポンスです(id 2・3・4 のデータは省略しています)。

populate なしと比べてレスポンスが大きくなっているはずです。ハイライト行のように、次のような追加フィールドが含まれます。

  • 記事カバーと各派生形式を含む image メディアフィールド
  • blocks ダイナミックゾーンと seo コンポーネントの第 1 階層フィールド
  • category リレーションとそのフィールド
  • 他言語訳の情報を示す localizations オブジェクト
Tip

ネストの深いコンポーネントをポピュレートするには コンポーネントをポピュレート を参照してください。


リクエスト例

GET /api/articles?populate=*

レスポンス例
{
"data": [
{
"id": 1,
"title": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "Basque dish",
"alternativeText": "Basque dish",
"caption": "Basque dish",
"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": "Want to give a try to a Strapi starter?",
"text": "❤️",
"commandLine": "git clone https://github.com/strapi/nextjs-corporate-starter.git"
}
],
"seo": {
"id": 1,
"documentId": "h7c8d0u3i3q5v1j3j3r4cxf",
"metaTitle": "Articles - FoodAdvisor",
"metaDescription": "Discover our articles about food, restaurants, bars and more! - FoodAdvisor",
"keywords": "food",
"metaRobots": null,
"structuredData": null,
"metaViewport": null,
"canonicalURL": null
},
"category": {
"data": {
"id": 4,
"documentId": "t1t3d9k6n1k5a6r8l7f8rox",
"name": "European",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
},
"localizations": {
"data": [
{
"id": 10,
"documentId": "h7c8d0u3i3q5v1j3j3r4cxf",
"title": "Voici pourquoi il faut essayer la cuisine basque, selon un chef basque",
"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": // truncated content
}
]
}
}
},
{
"id": 2,
// truncated content
},
{
"id": 3,
// truncated content
},
{
"id": 4,
// truncated content
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

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

ポピュレートするフィールドとリレーションを明示すれば、特定のものだけを返せます。そのためには名前を把握しておく必要があります。

この方法では 1 階層だけでも複数階層でも指定できます。次の図は、FoodAdvisor1 階層だけポピュレートした場合と 2 階層ポピュレートした場合の違いです。

FoodAdvisor データでの populate(図 2)

🤓 似た結果でもポピュレートの戦略は違えることがある

コンテンツ構造によっては、別のクエリでも似たデータを別の形で得られます。例えば FoodAdvisor では articlecategoryrestaurant がそれぞれ関係し合っています。3 種類を 1 回の GET で取りたい場合、次の 2 通りがあります。

  • articles をクエリし categories をポピュレートし、さらに categoriesrestaurants のネストしたリレーションをポピュレートする(2 階層ポピュレート
  • categories をクエリし、articlesrestaurants の両方をポピュレートする(categories が他 2 つと第 1 階層でつながっている場合、1 階層だけ

2 つの戦略を次の図に示します。

FoodAdvisor データでの populate(図 3)

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

高度なクエリパラメータの構文は手書きしにくいです。インタラクティブクエリビルダー で URL を生成することを推奨します。

このツールでは馴染みのある(JavaScript に近い)形で読みやすいリクエストを書け、クエリやポピュレートの違いを理解しやすくなります。例えば 2 階層ポピュレートでは populate をオブジェクトにし、複数リレーションを 1 階層だけポピュレートするときは配列にします。

オブジェクトとしての populate
(1 つのリレーションを複数階層):

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

配列としての populate
(複数リレーションを 1 階層だけ)

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

特定のリレーションを 1 階層だけポピュレート

populate パラメータを配列にすると、特定のリレーションを 1 階層だけポピュレートできます。

REST API は LHS bracket 記法(角括弧 [])を使うため、1 階層ポピュレートの構文は次のようになります。

ポピュレートするリレーション数構文の例
1 つだけpopulate[0]=a-relation-name
複数populate[0]=relation-name&populate[1]=another-relation-name&populate[2]=yet-another-relation-name

FoodAdvisor にクエリを送り、リレーションを 1 階層だけポピュレートする場合としない場合を比較します。

例: populate なし

populate がないと、/api/articles への GET は既定の属性だけを返します。

次の例は articles コンテンツタイプの 4 件すべてのレスポンスです。

メディア、リレーション、コンポーネント、ダイナミックゾーンは含まれないことに注目してください。


リクエスト例

GET /api/articles

レスポンス例
{
"data": [
{
"id": 1,
"documentId": "x2m0d7d9o4m2z3u2r2l9yes",
"title": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "What are chinese hamburgers and why aren't you eating them?",
"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 Places worth visiting for the food alone",
"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": "If you don't finish your plate in these countries, you might offend someone",
"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": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "European",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 2,
"documentId": "k6m6l9q0n6v9z2m3i0z5jah",
"title": "What are chinese hamburgers and why aren't you eating them?",
"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": "Chinese",
"slug": "chinese",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 3,
"title": "7 Places worth visiting for the food alone",
"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": "International",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 4,
"documentId": "t1t3d9k6n1k5a6r8l7f8rox",
"title": "If you don't finish your plate in these countries, you might offend someone",
"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": "International",
"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 bracket 記法(角括弧 [])を使うため、別のリレーションの内側にあるリレーションをポピュレートする場合のパラメータは次のような形になります。

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

Tip

高度なクエリパラメータは手書きしにくいです。インタラクティブクエリビルダー で URL を生成することを推奨します。例として、下の例で使う /api/articles?populate[category][populate][0]=restaurants は、次のオブジェクトをツールで変換して得られます。

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

FoodAdvisor ではコンテンツタイプ間に複数階層のリレーションがあります。例えば次のとおりです。

  • articlecategory とリレーションしている
  • category は複数の restaurant に割り当てられる

/api/articles へ 1 回の GET と適切な populate で、記事・レストラン・カテゴリの情報を同時に返せます。

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": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "European",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 2,
"documentId": "sen6qfgxcac13pwchf8xbu",
"title": "What are chinese hamburgers and why aren't you eating them?",
"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": "Chinese",
"slug": "chinese",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 3,
"documentId": "s9uu7rkukhfcsmj2e60b67",
"title": "7 Places worth visiting for the food alone",
"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": "International",
"slug": "international",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z"
}
}
},
{
"id": 4,
"documentId": "iy5ifm3xj8q0t8vlq6l23h",
"title": "If you don't finish your plate in these countries, you might offend someone",
"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": "International",
"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",
"title": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "European",
"slug": "european",
"createdAt": "2021-11-09T13:33:20.123Z",
"updatedAt": "2021-11-09T13:33:20.123Z",
"restaurants": {
"data": [
{
"id": 1,
"documentId": "ozlqrdxpnjb7wtvf6lp74v",
"name": "Mint Lounge",
"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,
// truncated content
},
{
"id": 10,
// truncated content
},
{
"id": 12,
// truncated content
},
{
"id": 21,
// truncated content
},
{
"id": 26,
// truncated content
}
]
}
}
}
},
{
"id": 2,
// truncated content
},
{
"id": 3,
// truncated content
},
{
"id": 4,
// truncated content
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

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

既定ではレスポンスにコンポーネントとダイナミックゾーンは含まれません。ダイナミックゾーン、コンポーネント、ネストしたコンポーネントはそれぞれ明示的にポピュレートする必要があります。

REST API は LHS bracket 記法(角括弧 [])を使うため、要素は 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 は、次のオブジェクトをツールで変換して得られます。

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

FoodAdvisor にはさまざまなコンポーネントがあり、さらにコンポーネントの中にコンポーネントがネストされています。例えば次のとおりです。

  • article コンテンツタイプに seo コンポーネントがある 1
  • seo の中に、繰り返し可能な metaSocial コンポーネントがネストされている 2
  • metaSocial には image メディアフィールドなど複数のフィールドがある 3

Content-Type Builder で見た FoodAdvisor の SEO コンポーネント構造

既定では /api/articles への GET のレスポンスにはこれらは含まれません。適切な populate があれば、1 回のリクエストですべて返せます。

populate[0]=seo(第 1 階層のコンポーネントのみ)と populate[0]=seo&populate[1]=seo.metaSocial(第 1 階層の内側の第 2 階層まで)のレスポンスを比較します。

例: 第 1 階層のコンポーネントのみ

seo コンポーネントだけをポピュレートすると 1 階層だけになり、次のようなレスポンスになります。ハイライトは seo コンポーネントです。

seo の内側にある metaSocial はまだ含まれていないことに注目してください。

リクエスト例

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

レスポンス例
{
"data": [
{
"id": 1,
"documentId": "md60m5cy3dula5g87x1uar",
"title": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "Articles - FoodAdvisor",
"metaDescription": "Discover our articles about food, restaurants, bars and more! - 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": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "e8cnux5ejxyqrejd5addfv",
"metaTitle": "Articles - FoodAdvisor",
"metaDescription": "Discover our articles about food, restaurants, bars and more! - FoodAdvisor",
"keywords": "food",
"metaRobots": null,
"structuredData": null,
"metaViewport": null,
"canonicalURL": null,
"metaSocial": [
{
"id": 1,
"documentId": "ks7xsp9fewoi0qljcz9qa0",
"socialNetwork": "Facebook",
"title": "Browse our best articles about food and restaurants ",
"description": "Discover our articles about food, restaurants, bars and more!"
}
]
}
},
{
"id": 2,
// truncated content
},
{
"id": 3,
// truncated content
},
{
"id": 4,
// truncated content
},
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}

ダイナミックゾーンをポピュレート

ダイナミックゾーンは性質上、非常に可変なコンテンツ構造です。ダイナミックゾーンとその中身をポピュレートするには、レスポンスに含める内容を明示的に定義する必要があります。

そのために、コンポーネントごとに on プロパティでポピュレートクエリを定義できます。

例として FoodAdvisor では次のとおりです。

  • article コンテンツタイプに blocks ダイナミックゾーンがある 1
  • そのゾーンには 3 種類のコンポーネントがある: relatedArticles 2faq 3CtaCommandLine 4。それぞれフィールド構成が異なる。
  • relatedArticles には記事コンテンツタイプへの articles リレーションがある 5

Content-Type Builder で見た FoodAdvisor の blocks ダイナミックゾーン

既定では /api/articles への GET では、深くネストしたフィールドやリレーションは含まれません。適切な populate と詳細なポピュレート戦略で、必要なデータだけを返せます。

Tip

高度なクエリパラメータは手書きしにくいです。インタラクティブクエリビルダー で URL を生成することを推奨します。例として、次の例の /api/articles?populate[blocks][on][blocks.related-articles][populate][articles][populate][0]=image&populate[blocks][on][blocks.cta-command-line][populate]=* は、次のオブジェクトをツールで変換して得られます。

{
populate: {
blocks: { // blocks ダイナミックゾーンをポピュレート
on: { // 詳細戦略で欲しいものを明示
'blocks.related-articles': {
populate: {
'articles': {
populate: ['image']
}
}
},
'blocks.cta-command-line': {
populate: '*'
}
},
},
},
}

共有ポピュレート戦略と詳細ポピュレート戦略の例で、返るレスポンスの違いを説明します。

blocks ダイナミックゾーンをポピュレートするとき、どのデータを含めるかを明示します。

次のレスポンス例では、ハイライトから次がわかります。

  • relatedArticles コンポーネントの articles リレーションを深くポピュレートし、関連記事の image メディアフィールドまで含めている。

  • CtaCommandLine にはすべてをポピュレートする指定だけがあり、faq コンポーネント向けの定義がないため、faq のデータは返らない。

詳細なポピュレーションのリクエスト例

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": "Here's why you have to try basque cuisine, according to a basque chef",
"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": "What are chinese hamburgers and why aren't you eating them?",
"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": "Want to give a try to a Strapi starter?",
"text": "❤️",
"commandLine": "git clone https://github.com/strapi/nextjs-corporate-starter.git"
}
]
},
{
"id": 2,
// …
},
{
"id": 3,
"documentId": "z5jnfvyuj07fogzh1kcbd3",
"title": "7 Places worth visiting for the food alone",
"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": "Want to give it a try with a brand new project?",
"text": "Up & running in seconds 🚀",
"commandLine": "npx create-strapi-app my-project --quickstart"
}
]
},
{
"id": 4,
// …
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}