理解 REST API 的 populate 参数
Page summary:在 REST API 查询中,
populate参数在响应中包含默认属性之外的额外字段、关系、组件和动态区域。使用populate=*获取所有一级深度关系,或者使用嵌套数组和片段语法显式指定字段以获取更深层或有选择的填充。🌐 The
populateparameter in REST API queries includes additional fields, relations, components, and dynamic zones in responses beyond default attributes. Usepopulate=*for all 1-level-deep relations, or explicitly specify fields with nested arrays and fragment syntax for deeper or selective population.
此页面的内容可能尚未与 Strapi 5 完全同步:
🌐 The content of this page might not be fully up-to-date with Strapi 5 yet:
- 所有概念信息和解释都是正确且最新的。
- 但是,在示例中,响应内容可能略有不同。
示例将在 Strapi 5.0.0(稳定版本)发布之后以及 FoodAdvisor 示例应用升级到 Strapi 5 后完全更新。
但是,响应示例略有不同不应妨碍你掌握本页所教授的基本概念。
🌐 However, having slightly different response examples should not prevent you from grasping the essential concepts taught in this page.
在使用 Strapi 的 REST API 查询内容类型时,默认情况下,响应只包含顶层字段,不包含任何关联、媒体字段、组件或动态区域。
🌐 When querying content-types with Strapi's REST API, by default, responses only include top-level fields and do not include any relations, media fields, components, or dynamic zones.
在 Strapi REST API 的上下文中,Populating 意味着通过返回比默认返回的字段更多的字段来在响应中包含额外的内容。你可以使用populate参数来实现这一点。
🌐 Populating in the context of the Strapi REST API means including additional content with your response by returning more fields than the ones returned by default. You use the populate parameter to achieve this.
在本指南中,示例是使用从 FoodAdvisor 示例应用附带的服务器查询的真实数据构建的。要自己测试示例,请设置 FoodAdvisor,在 /api/ 文件夹中启动服务器,并在发送查询之前确保为被查询的内容类型授予了适当的 find 权限。
本指南将详细解释以下用例:
🌐 The present guide will cover detailed explanations for the following use cases:
- 填充 所有字段和关系,深度1级,
- 填充 一些字段和关系,1 级深度,
- 填充一些字段和关系,几层深,
- 填充 组件,
- 填充动态区域。
填充多层通常被称为“深度填充”。
🌐 Populating several levels deep is often called "deep populate".
除了在查询中使用 populate 参数的各种方法外,你还可以构建自定义控制器作为一种解决方法来填充创建者字段(例如,createdBy 和 updatedBy)。这在专门的 如何填充创建者字段 指南中有说明。
🌐 In addition to the various ways of using the populate parameter in your queries, you can also build a custom controller as a workaround to populate creator fields (e.g., createdBy and updatedBy). This is explained in the dedicated How to populate creator fields guide.
填充所有关系和字段,深度为1级
🌐 Populate all relations and fields, 1 level deep
你可以通过单个查询返回所有关系、媒体字段、组件和动态区域。对于关系,这仅适用于一层深度,以防止性能问题和长时间的响应。
🌐 You can return all relations, media fields, components and dynamic zones with a single query. For relations, this will only work 1 level deep, to prevent performance issues and long response times.
要填充所有一级内容,请在查询中添加 populate=* 参数。
🌐 To populate everything 1 level deep, add the populate=* parameter to your query.
下图比较了 FoodAdvisor 示例应用在填充所有一级数据和未填充时返 回的数据:

让我们比较并解释使用和不使用此查询参数时会发生什么:
🌐 Let's compare and explain what happens with and without this query parameter:
示例:没有 populate
🌐 Example: Without populate
如果没有 populate 参数,对 /api/articles 的 GET 请求只会返回默认属性,不会返回任何媒体字段、关联、组件或动态区域。
🌐 Without the populate parameter, a GET request to /api/articles only returns the default attributes and does not return any media fields, relations, components or dynamic zones.
以下示例是来自 articles 内容类型的所有 4 个条目的完整响应。
🌐 The following example is the full response for all 4 entries from the articles content-types.
请注意,响应仅包含 title、slug、createdAt、updatedAt、publishedAt 和 locale 字段,以及由 CKEditor 插件处理的文章字段内容(ckeditor_content,为简洁起见已截断):
🌐 Notice how the response only includes the title, slug, createdAt, updatedAt, publishedAt, and locale fields, and the field content of the article as handled by the CKEditor plugin (ckeditor_content, truncated for brevity):
未填充
仅返回默认属性,不包含任何媒体字段、关系、组件或动态区域。
- cURL
- JavaScript
curl 'http://localhost:1337/api/articles' \
-H 'Authorization: Bearer <token>'
const response = await fetch(
'http://localhost:1337/api/articles',
{
headers: {
Authorization: 'Bearer <token>',
},
}
);
const data = await response.json();
{
"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=*
🌐 Example: With populate=*
使用 populate=* 参数,对 /api/articles 的 GET 请求也会返回所有媒体字段、一级关系、组件和动态区域。
🌐 With the populate=* parameter, a GET request to /api/articles also returns all media fields, first-level relations, components and dynamic zones.
以下示例是来自 articles 内容类型的所有 4 个条目中的第一个条目的完整响应(id 为 2、3 和 4 的文章数据为了简洁而被截断)。
🌐 The following example is the full response for the first of all 4 entries from the articles content-types (the data from articles with ids 2, 3, and 4 is truncated for brevity).
向下滚动查看响应大小比没有使用 populate 时大得多。响应现在包括额外的字段(见高亮行),例如:
🌐 Scroll down to see that the response size is much bigger than without populate. The response now includes additional fields (see highlighted lines) such as:
image媒体字段(存储关于文章封面 的所有信息,包括其所有不同格式),blocks动态区域和seo组件的一级字段,category关系及其字段,- 甚至还有一些关于以其他语言翻译的文章的信息,如
localizations对象所示。
要填充深层嵌套的组件,请参阅填充组件部分。
🌐 To populate deeply nested components, see the populate components section.
使用 populate=*
返回所有媒体字段、一阶关系、组件和动态区域。
- cURL
- JavaScript
curl 'http://localhost:1337/api/articles?populate=*' \
-H 'Authorization: Bearer <token>'
const response = await fetch(
'http://localhost:1337/api/articles?populate=*',
{
headers: {
Authorization: 'Bearer <token>',
},
}
);
const data = await response.json();
填充特定的关系和字段
🌐 Populate specific relations and fields
你也可以通过明确定义要填充的内容来填充特定的关系和字段。这要求你知道要填充的字段和关系的名称。
🌐 You can also populate specific relations and fields, by explicitly defining what to populate. This requires that you know the name of fields and relations to populate.
通过这种方式填充的关系和字段可以有1级或多级深度。下图比较了当你填充1级深度与2级深度时, FoodAdvisor 示例应用返回的数据:

根据你的内容结构,你可能会发现使用不同的查询以不同的方式呈现类似的数据。例如,FoodAdvisor 示例应用包含文章、类别和餐厅内容类型,它们以不同的方式相互关联。这意味着,如果你想在单个 GET 请求中获取关于这三种内容类型的数据,你有两个选择:
下图说明了这两种不同的策略:
🌐 The 2 different strategies are illustrated in the following diagram:

作为对象填充与作为数组填充:使用交互式查询构建器
高级查询参数的语法手动构建可能相当复杂。我们建议你使用我们的交互式查询构建器工具来生成 URL。
🌐 The syntax for advanced query parameters can be quite complex to build manually. We recommend you use our interactive query builder tool to generate the URL.
使用这个工具,你将使用熟悉的(JavaScript)格式编写清晰且易读的请求,这应该有助于你理解不同查询和不同填充方式之间的差异。例如,深度填充 2 级意味着将 populate 用作对象,而深度填充 1 级的多个关系意味着将 populate 用作数组:
🌐 Using this tool, you will write clean and readable requests in a familiar (JavaScript) format, which should help you understand the differences between different queries and different ways of populating. For instance, populating 2 levels deep implies using populate as an object, while populating several relations 1 level deep implies using populate as an array:
填充为对象
(填充 1 个关系多个级别):
{
populate: {
category: {
populate: ['restaurants'],
},
},
}
填充为数组
(填充许多 1 层深的关系)
{
populate: [
'articles',
'restaurants'
],
}