REST API: Population & Field Selection
Page summary:
Use the
populateparameter to include relations, media fields, components, and dynamic zones in REST API responses. Use thefieldsparameter to return only specific fields.
The REST API by default does not populate any relations, media fields, components, or dynamic zones. Use the populate parameter to populate specific fields. Use the fields parameter to return only specific fields with the query results.
Strapi takes advantage of the ability of the `qs` library to parse nested objects to create more complex queries.
Use qs directly to generate complex queries instead of creating them manually. Examples in this documentation showcase how you can use qs.
You can also use the interactive query builder if you prefer playing with our online tool instead of generating queries with qs on your machine.
Field selection
Queries can accept a fields parameter to select only some fields. By default, the REST API only returns the following types of fields:
- string types:
string,text,richtext,enumeration,email,password, anduid, - date types:
date,time,datetime, andtimestamp, - number types:
integer,biginteger,float, anddecimal, - generic types:
boolean,array, andJSON.
| Use case | Example parameter syntax |
|---|---|
| Select a single field | fields=name |
| Select multiple fields | fields[0]=name&fields[1]=description |
Field selection does not work on relational, media, component, or dynamic zone fields. To populate these fields, use the populate parameter.
GET /api/restaurants?fields[0]=name&fields[1]=description
JavaScript query (built with the qs library)
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
fields: ['name', 'description'],
},
{
encodeValuesOnly: true, // prettify URL
}
);
await request(`/api/users?${query}`);
{
"data": [
{
"id": 4,
"Name": "Pizzeria Arrivederci",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "Specialized in pizza, we invite you to rediscover our classics, such as 4 Formaggi or Calzone, and our original creations such as Do Luigi or Nduja."
}
]
}
],
"documentId": "lr5wju2og49bf820kj9kz8c3"
},
// …
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}
Population
The REST API by default does not populate any type of fields, so it will not populate relations, media fields, components, or dynamic zones unless you pass a populate parameter to populate various field types. Populated relations always return full objects; the REST API currently cannot return just an array of IDs.
The find permission must be enabled for the content-types that are being populated. If a role does not have access to a content-type, the content-type will not be populated (see Users & Permissions for additional information on how to enable find permissions for content-types).
You can use the populate parameter alone or in combination with multiple operators for more control over the population.
The following table lists populate use cases with example syntax. Each row links to the Understanding populate guide for details:
| Use case | Example parameter syntax | Detailed explanations to read |
|---|---|---|
| Populate everything, 1 level deep, including media fields, relations, components, and dynamic zones | populate=* | Populate all relations and fields, 1 level deep |
| Populate one relation, 1 level deep | populate=a-relation-name | Populate 1 level deep for specific relations |
| Populate several relations, 1 level deep | populate[0]=relation-name&populate[1]=another-relation-name&populate[2]=yet-another-relation-name | Populate 1 level deep for specific relations |
| Populate some relations, several levels deep | populate[root-relation-name][populate][0]=nested-relation-name | Populate several levels deep for specific relations |
| Populate a component | populate[0]=component-name | Populate components |
| Populate a component and one of its nested components | populate[0]=component-name&populate[1]=component-name.nested-component-name | Populate components |
| Populate a dynamic zone (only its first-level elements) | populate[0]=dynamic-zone-name | Populate dynamic zones |
| Populate a dynamic zone and its nested elements and relations, using a precisely defined, detailed population strategy | populate[dynamic-zone-name][on][component-category.component-name][populate][relation-name][populate][0]=field-name | Populate dynamic zones |
To build complex queries with multiple-level population, use the interactive query builder tool. For more detailed explanations and examples, see the REST API guides.
Combining population with other operators
You can combine the populate operator with other operators such as field selection, filters, and sort in the population queries.
The population and pagination operators cannot be combined.
Populate with field selection
fields and populate can be combined.
GET /api/articles?fields[0]=title&fields[1]=slug&populate[headerImage][fields][0]=name&populate[headerImage][fields][1]=url
JavaScript query (built with the qs library)
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
fields: ['title', 'slug'],
populate: {
headerImage: {
fields: ['name', 'url'],
},
},
},
{
encodeValuesOnly: true, // prettify URL
}
);
await request(`/api/articles?${query}`);
{
"data": [
{
"id": 1,
"documentId": "h90lgohlzfpjf3bvan72mzll",
"title": "Test Article",
"slug": "test-article",
"headerImage": {
"id": 1,
"documentId": "cf07g1dbusqr8mzmlbqvlegx",
"name": "17520.jpg",
"url": "/uploads/17520_73c601c014.jpg"
}
}
],
"meta": {
// ...
}
}
Populate with filtering
filters and populate can be combined.
GET /api/articles?populate[categories][sort][0]=name%3Aasc&populate[categories][filters][name][$eq]=Cars
JavaScript query (built with the qs library)
The query URL above was built using the `qs` library.
qs can be run locally on your machine, as shown in the following code example, or you can use our interactive query builder online tool.
const qs = require('qs');
const query = qs.stringify(
{
populate: {
categories: {
sort: ['name:asc'],
filters: {
name: {
$eq: 'Cars',
},
},
},
},
},
{
encodeValuesOnly: true, // prettify URL
}
);
await request(`/api/articles?${query}`);
{
"data": [
{
"id": 1,
"documentId": "a1b2c3d4e5d6f7g8h9i0jkl",
"title": "Test Article",
// ...
"categories": {
"data": [
{
"id": 2,
"documentId": "jKd8djla9ndalk98hflj3",
"name": "Cars"
// ...
}
]
}
}
}
],
"meta": {
// ...
}
}