REST API: Filtering, Locale, and Publication State
The REST API offers the ability to filter results found with its "Get entries" method.
Using optional Strapi features can provide some more filters:
- If the Internationalization (i18n) plugin is enabled on a content-type, it's possible to filter by locale.
- If the Draft & Publish is enabled, it's possible to filter based on a
published
(default) ordraft
status.
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.
Filtering
Queries can accept a filters
parameter with the following syntax:
GET /api/:pluralApiId?filters[field][operator]=value
The following operators are available:
Operator | Description |
---|---|
$eq | Equal |
$eqi | Equal (case-insensitive) |
$ne | Not equal |
$nei | Not equal (case-insensitive) |
$lt | Less than |
$lte | Less than or equal to |
$gt | Greater than |
$gte | Greater than or equal to |
$in | Included in an array |
$notIn | Not included in an array |
$contains | Contains |
$notContains | Does not contain |
$containsi | Contains (case-insensitive) |
$notContainsi | Does not contain (case-insensitive) |
$null | Is null |
$notNull | Is not null |
$between | Is between |
$startsWith | Starts with |
$startsWithi | Starts with (case-insensitive) |
$endsWith | Ends with |
$endsWithi | Ends with (case-insensitive) |
$or | Joins the filters in an "or" expression |
$and | Joins the filters in an "and" expression |
$not | Joins the filters in an "not" expression |
By default, the filters can only be used from find
endpoints generated by the Content-type Builder and the CLI.
Example: Find users having 'John' as a first name
You can use the $eq
filter operator to find an exact match.
GET /api/users?filters[username][$eq]=John
{
"data": [
{
"id": 1,
"documentId": "znrlzntu9ei5onjvwfaalu2v",
"username": "John",
"email": "john@test.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2021-12-03T20:08:17.740Z",
"updatedAt": "2021-12-03T20:08:17.740Z"
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
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({
filters: {
username: {
$eq: 'John',
},
},
}, {
encodeValuesOnly: true, // prettify URL
});
await request(`/api/users?${query}`);
Example: Find multiple restaurants with ids 3, 6,8
You can use the $in
filter operator with an array of values to find multiple exact values.
GET /api/restaurants?filters[id][$in][0]=6&filters[id][$in][1]=8
{
"data": [
{
"id": 6,
"documentId": "ethwxjxtvuxl89jq720e38uk",
"name": "test6",
// ...
},
{
"id": 8,
"documentId": "cf07g1dbusqr8mzmlbqvlegx",
"name": "test8",
// ...
},
],
"meta": {
// ...
}
}
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({
filters: {
id: {
$in: [3, 6, 8],
},
},
}, {
encodeValuesOnly: true, // prettify URL
});
await request(`/api/restaurants?${query}`);
Complex filtering
Complex filtering is combining multiple filters using advanced methods such as combining $and
& $or
. This allows for more flexibility to request exactly the data needed.
GET /api/books?filters[$or][0][date][$eq]=2020-01-01&filters[$or][1][date][$eq]=2020-01-02&filters[author][name][$eq]=Kai%20doe
{
"data": [
{
"id": 1,
"documentId": "rxngxzclq0zdaqtvz67hj38d",
"name": "test1",
"date": "2020-01-01",
// ...
},
{
"id": 2,
"documentId": "kjkhff4e269a50b4vi16stst",
"name": "test2",
"date": "2020-01-02",
// ...
}
],
"meta": {
// ...
}
}
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({
filters: {
$or: [
{
date: {
$eq: '2020-01-01',
},
},
{
date: {
$eq: '2020-01-02',
},
},
],
author: {
name: {
$eq: 'Kai doe',
},
},
},
}, {
encodeValuesOnly: true, // prettify URL
});
await request(`/api/books?${query}`);
Deep filtering
Deep filtering is filtering on a relation's fields.
- Querying your API with deep filters may cause performance issues. If one of your deep filtering queries is too slow, we recommend building a custom route with an optimized version of the query.
- Deep filtering isn't available for polymorphic relations (e.g., dynamic zones and media fields).
- Relations, media fields, components, and dynamic zones are not populated by default. Use the
populate
parameter to populate these data structures (seepopulate
documentation) - It is not possible to filter on dynamic zones or media fields.
GET /api/restaurants?filters[chef][restaurants][stars][$eq]=5
{
"data": [
{
"id": 1,
"documentId": "cvsz61qg33rtyv1qljb1nrtg",
"name": "GORDON RAMSAY STEAK",
"stars": 5
// ...
},
{
"id": 2,
"documentId": "uh17h7ibw0g8thit6ivi71d8",
"name": "GORDON RAMSAY BURGER",
"stars": 5
// ...
}
],
"meta": {
// ...
}
}
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({
filters: {
chef: {
restaurants: {
stars: {
$eq: 5,
},
},
},
},
}, {
encodeValuesOnly: true, // prettify URL
});
await request(`/api/restaurants?${query}`);
Locale
- The Internationalization (i18n) feature should be installed.
- Localization should be enabled for the content-type.
The locale
API parameter can be used to work with entries from a specific locale (see Internationalization documentation).
Status
The Draft & Publish feature should be enabled.
Queries can accept a status
parameter to fetch documents based on their status:
published
: returns only the published version of documents (default)draft
: returns only the draft version of documents
In the response data, the publishedAt
field is null
for drafts.
Since published versions are returned by default, passing no status parameter is equivalent to passing status=published
.
GET /api/articles?status=draft
{
"data": [
// …
{
"id": 5,
"documentId": "znrlzntu9ei5onjvwfaalu2v",
"Name": "Biscotte Restaurant",
"Description": [
{
"type": "paragraph",
"children": [
{
"type": "text",
"text": "This is the draft version."
}
]
}
],
"createdAt": "2024-03-06T13:43:30.172Z",
"updatedAt": "2024-03-06T21:38:46.353Z",
"publishedAt": null,
"locale": "en"
},
// …
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 4
}
}
}
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({
status: 'draft',
}, {
encodeValuesOnly: true, // prettify URL
});
await request(`/api/articles?${query}`);