Learn how to set the default "populate" options via route middleware in Strapi 5.
Instead of passing "populate" on each request from the frontend, the can handle this functionality via route-based middleware in the backend. This will allow you to keep your frontend requests lean and organized.
You can also use this to control what data will be returned by default and not allow the user to add additional populate options in the frontend.
What is Route Middleware?
In Strapi, Route Middleware has a more limited scope and is configured and used as middleware at the route level. You can learn more in the Strapi documentation. Now, let's jump in and learn how to set this up.
Sample Project Setup
Let's quickly set up a sample project to follow along. We will start by creating a new Strapi project with the following command:
npx create-strapi-app@latest my-strapi-app
You will be prompted with the following questions, the first one will ask if you would like to login or sign up to Strapi Cloud, we will skip this by selecting Skip
.
? Please log in or sign up. (Use arrow keys)
Login/Sign up
❯ Skip
Next, you will be asked the following question:
? Do you want to use the default database (sqlite) ? Y
? Start with an example structure & data? Yes
? Start with Typescript? Yes
? Install dependencies with npm? Yes
? Initialize a git repository? Yes
note: Make sure you select Yes
for Start with an example structure & data. This will give you some sample content to work with.
Once all the dependencies are installed, you will be able to start the Strapi server with the following command:
cd my-strapi-app
yarn develop
Once the server is running, you will be able to access the Strapi admin dashboard at http://localhost:1337/admin
.
Go ahead and create your first Admin User so you can access the admin panel.
Once logged in, you will be redirected to the dashboard. Navigate to Content Manager
and select Article collection type and let's publish the content so we can access it via the API.
Once published, before we can access the content, let's make sure that the API is enabled by going to Settings
> Users & Permissions plugin
> Roles
> Public
, selecting our Article collection type and enabling find
and findOne
permissions and save.
We will make a GET
request to http://localhost:1337/api/articles
and we should see the following response:
Now that is done, let's use Postman to query the content and see what we have.
1{
2 "data": [
3 {
4 "id": 6,
5 "documentId": "kpjqhi7i2rp7ll7o6tqtusmu",
6 "title": "A bug is becoming a meme on the internet",
7 "description": "How a bug on MySQL is becoming a meme on the internet",
8 "slug": "a-bug-is-becoming-a-meme-on-the-internet",
9 "createdAt": "2025-03-20T04:13:35.220Z",
10 "updatedAt": "2025-03-20T04:13:35.220Z",
11 "publishedAt": "2025-03-20T04:24:24.160Z"
12 },
13 {
14 "id": 7,
15 "documentId": "lwl33j9wt1nmctvni5zvfd80",
16 "title": "Beautiful picture",
17 "description": "Description of a beautiful picture",
18 "slug": "beautiful-picture",
19 "createdAt": "2025-03-20T04:13:35.361Z",
20 "updatedAt": "2025-03-20T04:13:35.361Z",
21 "publishedAt": "2025-03-20T04:24:24.160Z"
22 },
23 {
24 "id": 8,
25 "documentId": "dp0do80oh649p7amcnieakin",
26 "title": "The internet's Own boy",
27 "description": "Follow the story of Aaron Swartz, the boy who could change the world",
28 "slug": "the-internet-s-own-boy",
29 "createdAt": "2025-03-20T04:13:35.069Z",
30 "updatedAt": "2025-03-20T04:13:35.069Z",
31 "publishedAt": "2025-03-20T04:24:24.160Z"
32 },
33 {
34 "id": 9,
35 "documentId": "d6psnctplfh04jpkv2ajbs2h",
36 "title": "This shrimp is awesome",
37 "description": "Mantis shrimps, or stomatopods, are marine crustaceans of the order Stomatopoda.",
38 "slug": "this-shrimp-is-awesome",
39 "createdAt": "2025-03-20T04:13:35.110Z",
40 "updatedAt": "2025-03-20T04:13:35.110Z",
41 "publishedAt": "2025-03-20T04:24:24.160Z"
42 },
43 {
44 "id": 10,
45 "documentId": "c2mxad5p1qexlzoswqpq1cqm",
46 "title": "What's inside a Black Hole",
47 "description": "Maybe the answer is in this article, or not...",
48 "slug": "what-s-inside-a-black-hole",
49 "createdAt": "2025-03-20T04:13:35.390Z",
50 "updatedAt": "2025-03-20T04:13:35.390Z",
51 "publishedAt": "2025-03-20T04:24:24.160Z"
52 }
53 ],
54 "meta": {
55 "pagination": {
56 "page": 1,
57 "pageSize": 25,
58 "pageCount": 1,
59 "total": 5
60 }
61 }
62}
Great our API is working and we can access the content. Although, we are not getting all of out data, we will address this in the next section.
By default, Strapi will only return the top level fields. And any relations we would need to tell Strapi specifically to populate.
This allows us to keep our API responses clean and manageable. And only ask for the data we need.
Sample Content Structure
In our Strapi Article data we have the following fields and relations.
- title
- description
- slug
They are top level
fields and will be populated by default.
- cover
- author
- category
- blocks
Are relations
and will not be populated by default. We will need to let Strapi know what relations we want to populate.
If you like more about populate and filtering, you can read more in the Strapi documentation.
But first, let's take a look at why you might want to add middleware for this use case in the first place.
The Problem
By default, population structure needs to be defined and sent on each client-side
request, else the request will return only top-level parent content.
As we saw above, making a GET
request to localhost:1337/api/articles
returns the following:
1// data
2{
3 "id": 6,
4 "documentId": "kpjqhi7i2rp7ll7o6tqtusmu",
5 "title": "A bug is becoming a meme on the internet",
6 "description": "How a bug on MySQL is becoming a meme on the internet",
7 "slug": "a-bug-is-becoming-a-meme-on-the-internet",
8 "createdAt": "2025-03-20T04:13:35.220Z",
9 "updatedAt": "2025-03-20T04:13:35.220Z",
10 "publishedAt": "2025-03-20T04:24:24.160Z"
11},
12// data
This is not ideal, seeing as important data has been excluded, such as the cover
, author
, category
, and blocks
information.
Populate = *
An easy solution to the problem above involves adding populate=*
to the initial query.
localhost:1337/api/articles?populate=*
returns the following:
1// localhost:1337/api/articles?populate=*
2{
3 "data": [
4 {
5 "id": 6,
6 "documentId": "kpjqhi7i2rp7ll7o6tqtusmu",
7 "title": "A bug is becoming a meme on the internet",
8 "description": "How a bug on MySQL is becoming a meme on the internet",
9 "slug": "a-bug-is-becoming-a-meme-on-the-internet",
10 "createdAt": "2025-03-20T04:13:35.220Z",
11 "updatedAt": "2025-03-20T04:13:35.220Z",
12 "publishedAt": "2025-03-20T04:24:24.160Z",
13 "cover": {
14 "id": 7,
15 "documentId": "v8efgbnol1xxu7nwunyxardr",
16 "name": "a-bug-is-becoming-a-meme-on-the-internet",
17 "alternativeText": "An image uploaded to Strapi called a-bug-is-becoming-a-meme-on-the-internet",
18 "caption": "a-bug-is-becoming-a-meme-on-the-internet",
19 "width": 3628,
20 "height": 2419,
21 "formats": {
22 "thumbnail": {
23 "name": "thumbnail_a-bug-is-becoming-a-meme-on-the-internet",
24 "hash": "thumbnail_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2",
25 "ext": ".jpeg",
26 "mime": "image/jpeg",
27 "path": null,
28 "width": 234,
29 "height": 156,
30 "size": 6.73,
31 "sizeInBytes": 6728,
32 "url": "/uploads/thumbnail_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg"
33 },
34 "medium": {
35 "name": "medium_a-bug-is-becoming-a-meme-on-the-internet",
36 "hash": "medium_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2",
37 "ext": ".jpeg",
38 "mime": "image/jpeg",
39 "path": null,
40 "width": 750,
41 "height": 500,
42 "size": 33.59,
43 "sizeInBytes": 33590,
44 "url": "/uploads/medium_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg"
45 },
46 "large": {
47 "name": "large_a-bug-is-becoming-a-meme-on-the-internet",
48 "hash": "large_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2",
49 "ext": ".jpeg",
50 "mime": "image/jpeg",
51 "path": null,
52 "width": 1000,
53 "height": 666,
54 "size": 50.97,
55 "sizeInBytes": 50972,
56 "url": "/uploads/large_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg"
57 },
58 "small": {
59 "name": "small_a-bug-is-becoming-a-meme-on-the-internet",
60 "hash": "small_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2",
61 "ext": ".jpeg",
62 "mime": "image/jpeg",
63 "path": null,
64 "width": 500,
65 "height": 333,
66 "size": 19.25,
67 "sizeInBytes": 19245,
68 "url": "/uploads/small_a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg"
69 }
70 },
71 "hash": "a_bug_is_becoming_a_meme_on_the_internet_308f213bf2",
72 "ext": ".jpeg",
73 "mime": "image/jpeg",
74 "size": 234.02,
75 "url": "/uploads/a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg",
76 "previewUrl": null,
77 "provider": "local",
78 "provider_metadata": null,
79 "createdAt": "2025-03-20T04:13:35.216Z",
80 "updatedAt": "2025-03-20T04:13:35.216Z",
81 "publishedAt": "2025-03-20T04:13:35.216Z"
82 },
83 "author": {
84 "id": 2,
85 "documentId": "c8kq3zu2elrr7jumezkc6g1l",
86 "name": "Sarah Baker",
87 "email": "sarahbaker@strapi.io",
88 "createdAt": "2025-03-20T04:13:34.369Z",
89 "updatedAt": "2025-03-20T04:13:34.369Z",
90 "publishedAt": "2025-03-20T04:13:34.369Z"
91 },
92 "category": {
93 "id": 2,
94 "documentId": "v2o8ceovywpa7dhawebblck2",
95 "name": "tech",
96 "slug": "tech",
97 "description": null,
98 "createdAt": "2025-03-20T04:13:34.079Z",
99 "updatedAt": "2025-03-20T04:13:34.079Z",
100 "publishedAt": "2025-03-20T04:13:34.079Z"
101 },
102 "blocks": [
103 {
104 "__component": "shared.rich-text",
105 "id": 12,
106 "body": "## Probant \n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. \n\n## Abit sua\n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. "
107 },
108 {
109 "__component": "shared.quote",
110 "id": 7,
111 "title": "Thelonius Monk",
112 "body": "You've got to dig it to dig it, you dig?"
113 },
114 {
115 "__component": "shared.media",
116 "id": 7
117 },
118 {
119 "__component": "shared.rich-text",
120 "id": 13,
121 "body": "## Spatiantia astra \n\nFoeda, medio silva *errandum*: onus formam munere. Mutata bibulis est auxiliare arces etiamnunc verbis virgineo Priamidas illa Thescelus, nam fit locis lucis auras. Exitus hospes gratulor ut pondere [speslimite](http://www.curas.io/figuram); quid habent, Avernales faciente de. Pervenit Ino sonabile supplex cognoscenti vires, Bacchumque errat miserarum venandi dignabere dedisti. Discrimina iuncosaque virgaque tot sine superest [fissus](http://quos.org/sitet.aspx). Non color esset potest non sumit, sed vix arserat. Nisi immo silva tantum pectusque quos pennis quisquam artus!"
122 },
123 {
124 "__component": "shared.slider",
125 "id": 6
126 }
127 ]
128 }
129 ],
130 "meta": {
131 "pagination": {
132 "page": 1,
133 "pageSize": 25,
134 "pageCount": 1,
135 "total": 5
136 }
137 }
138}
While this does return more data, the main flaw with this approach is that you don't have control over what data is returned. You are still not receiving valuable information, such as the image in our shared.media
component found in the blocks
array, or author's avatar
image while also receiving data you might not care about.
Getting Granular
Instead of using populate=*
, you can filter the query using LHS Bracket syntax.
The query might look like this:
1/api/articles?populate[cover][fields][0]=url&populate[cover][fields][1]=alternativeText&populate[author][populate][avatar][fields][0]=url&populate[author][populate][avatar][fields][1]=alternativeText&populate[category]=true&populate[blocks][on][shared.media][populate][file][fields][0]=url&populate[blocks][on][shared.media][populate][file][fields][1]=alternativeText&populate[blocks][on][shared.quote]=true&populate[blocks][on][shared.rich-text]=true&populate[blocks][on][shared.seo][populate][shareImage][fields][0]=url&populate[blocks][on][shared.seo][populate][shareImage][fields][1]=alternativeText&populate[blocks][on][shared.slider][populate][files][fields][0]=url&populate[blocks][on][shared.slider][populate][files][fields][1]=alternativeText
You can test by making a GET
request to following url.
While this correctly returns the data specified, it is not feasible to use. This query is quite unruly and certainly not something you'd want to consistently use throughout your application.
Enter... Query-String
Using query-string, we can implement the same query as above in a much more readable and reusable manner. The query can easily be used directly in the front-end of our application.
For example:
1const qs = require("qs");
2const query = qs.stringify({
3 populate: {
4 cover: {
5 fields: ["url", "alternativeText"],
6 },
7
8 author: {
9 populate: {
10 avatar: {
11 fields: ["url", "alternativeText"],
12 },
13 },
14 },
15
16 category: true,
17
18 blocks: {
19 on: {
20 "shared.media": {
21 populate: {
22 file: {
23 fields: ["url", "alternativeText"],
24 },
25 },
26 },
27 "shared.quote": true,
28 "shared.rich-text": true,
29 "shared.seo": {
30 populate: {
31 shareImage: {
32 fields: ["url", "alternativeText"],
33 },
34 },
35 },
36 "shared.slider": {
37 populate: {
38 files: {
39 fields: ["url", "alternativeText"],
40 },
41 },
42 },
43 },
44 },
45 },
46});
47// `localhost:1337/api/articles?${query}`
It successfully returns the same result as the above query where we used bracket syntax:
1{
2 "data": [
3 {
4 "id": 6,
5 "documentId": "kpjqhi7i2rp7ll7o6tqtusmu",
6 "title": "A bug is becoming a meme on the internet",
7 "description": "How a bug on MySQL is becoming a meme on the internet",
8 "slug": "a-bug-is-becoming-a-meme-on-the-internet",
9 "createdAt": "2025-03-20T04:13:35.220Z",
10 "updatedAt": "2025-03-20T04:13:35.220Z",
11 "publishedAt": "2025-03-20T04:24:24.160Z",
12 "cover": {
13 "id": 7,
14 "documentId": "v8efgbnol1xxu7nwunyxardr",
15 "url": "/uploads/a_bug_is_becoming_a_meme_on_the_internet_308f213bf2.jpeg",
16 "alternativeText": "An image uploaded to Strapi called a-bug-is-becoming-a-meme-on-the-internet"
17 },
18 "author": {
19 "id": 2,
20 "documentId": "c8kq3zu2elrr7jumezkc6g1l",
21 "name": "Sarah Baker",
22 "email": "sarahbaker@strapi.io",
23 "createdAt": "2025-03-20T04:13:34.369Z",
24 "updatedAt": "2025-03-20T04:13:34.369Z",
25 "publishedAt": "2025-03-20T04:13:34.369Z",
26 "avatar": {
27 "id": 2,
28 "documentId": "oh90qnqdun84hhsosx9w6oph",
29 "url": "/uploads/sarahbaker_strapi_2e6cc8a9ae.jpeg",
30 "alternativeText": "An image uploaded to Strapi called sarahbaker@strapi"
31 }
32 },
33 "category": {
34 "id": 2,
35 "documentId": "v2o8ceovywpa7dhawebblck2",
36 "name": "tech",
37 "slug": "tech",
38 "description": null,
39 "createdAt": "2025-03-20T04:13:34.079Z",
40 "updatedAt": "2025-03-20T04:13:34.079Z",
41 "publishedAt": "2025-03-20T04:13:34.079Z"
42 },
43 "blocks": [
44 {
45 "__component": "shared.rich-text",
46 "id": 12,
47 "body": "## Probant \n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. \n\n## Abit sua\n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. "
48 },
49 {
50 "__component": "shared.quote",
51 "id": 7,
52 "title": "Thelonius Monk",
53 "body": "You've got to dig it to dig it, you dig?"
54 },
55 {
56 "__component": "shared.media",
57 "id": 7,
58 "file": {
59 "id": 4,
60 "documentId": "rsr8hyxsbt6d5w04qui0vvbw",
61 "url": "/uploads/coffee_art_a78efac608.jpeg",
62 "alternativeText": "An image uploaded to Strapi called coffee-art"
63 }
64 },
65 {
66 "__component": "shared.rich-text",
67 "id": 13,
68 "body": "## Spatiantia astra \n\nFoeda, medio silva *errandum*: onus formam munere. Mutata bibulis est auxiliare arces etiamnunc verbis virgineo Priamidas illa Thescelus, nam fit locis lucis auras. Exitus hospes gratulor ut pondere [speslimite](http://www.curas.io/figuram); quid habent, Avernales faciente de. Pervenit Ino sonabile supplex cognoscenti vires, Bacchumque errat miserarum venandi dignabere dedisti. Discrimina iuncosaque virgaque tot sine superest [fissus](http://quos.org/sitet.aspx). Non color esset potest non sumit, sed vix arserat. Nisi immo silva tantum pectusque quos pennis quisquam artus!"
69 },
70 {
71 "__component": "shared.slider",
72 "id": 6,
73 "files": [
74 {
75 "id": 4,
76 "documentId": "rsr8hyxsbt6d5w04qui0vvbw",
77 "url": "/uploads/coffee_art_a78efac608.jpeg",
78 "alternativeText": "An image uploaded to Strapi called coffee-art"
79 },
80 {
81 "id": 5,
82 "documentId": "ji7jrinptpix4oye01imefhm",
83 "url": "/uploads/coffee_beans_71768dc0f4.jpeg",
84 "alternativeText": "An image uploaded to Strapi called coffee-beans"
85 }
86 ]
87 }
88 ]
89 }
90 ],
91 "meta": {
92 "pagination": {
93 "page": 1,
94 "pageSize": 25,
95 "pageCount": 1,
96 "total": 5
97 }
98 }
99}
For many use cases, this will be the logical end. However, if you find that you are re-using the same query over and over again, read on.
Query Logic in Middleware
Now that you know how to build useful queries, you can look at optimizing the process further by adding a query directly into route-based middleware.
Initializing the New Middleware
In Strapi, you can generate boilerplate code directly from the CLI. In your terminal, run the command:
yarn strapi generate
From there, navigate to middleware
.
$ strapi generate
? Strapi Generators
api - Generate a basic API
controller - Generate a controller for an API
content-type - Generate a content type for an API
policy - Generate a policy for an API
❯ middleware - Generate a middleware for an API
migration - Generate a migration
service - Generate a service for an API
You will be prompted to name the middleware.
? Middleware name article-populate
I called mine article-populate
.
Then, you will need to select where you want to add this middleware.
? Where do you want to add this middleware?
Add middleware to root of project
❯ Add middleware to an existing API
Add middleware to an existing plugin
We will choose Add middleware to an existing API
since we only want it to run on the article route.
? Which API is this for?
about
❯ article
author
category
global
Once you select the API it will create the middleware in the src > api > article > middlewares
directory.
✔ ++ /api/article/middlewares/article-populate.ts
✨ Done in 150.18s.
Now in the Strapi project, if you navigate to src > api > article > middlewares > article-populate.ts
, you will see the following boilerplate:
1/**
2 * `article-populate` middleware
3 */
4
5import type { Core } from "@strapi/strapi";
6
7export default (config, { strapi }: { strapi: Core.Strapi }) => {
8 // Add your own logic here.
9 return async (ctx, next) => {
10 strapi.log.info("In article-populate middleware.");
11
12 await next();
13 };
14};
Enable Middleware on Route
Before utilizing the middleware, you first need to enable it on the route.
If you head to src > api > article > routes > article.ts
, you'll see the default route configuration:
1/**
2 * article router.
3 */
4
5import { factories } from "@strapi/strapi";
6
7export default factories.createCoreRouter("api::article.article");
Edit this file as follows:
1/**
2 * article router.
3 */
4
5import { factories } from "@strapi/strapi";
6
7export default factories.createCoreRouter("api::article.article", {
8 config: {
9 find: {
10 middlewares: ["api::article.article-populate"],
11 },
12 findOne: {
13 middlewares: ["api::article.article-populate"],
14 },
15 },
16});
We will need to add the middleware to the find
and findOne
routes.
Pro Tip: If you can't remember the internal UIDs of the middleware, which is
api::article.article-populate
, run the command below:
yarn strapi middlewares:list
This will give you a list of all internal middleware UIDs in your project.
To see all of the available customizations for core routes, check out the docs.
Adding Logic to the Middleware
Now that the middleware has been initialized in your project and added to the article
route, it's time to add some logic.
The purpose of this middleware is so you do not need to build your query on the frontend to return the data you are looking to fetch.
By adding your logic directly to the middleware, all of the querying will happen automatically when you head to the localhost:1337/api/article
route.
Instead of writing your query on the frontend, add it directly to the middleware, as such:
1// src > api > article > middlewares > article-populate.ts
2
3/**
4 * `article-populate` middleware
5 */
6
7import type { Core } from "@strapi/strapi";
8
9const populate = {
10 cover: {
11 fields: ["url", "alternativeText"],
12 },
13
14 author: {
15 populate: {
16 avatar: {
17 fields: ["url", "alternativeText"],
18 },
19 },
20 },
21
22 category: true,
23
24 blocks: {
25 on: {
26 "shared.media": {
27 populate: {
28 file: {
29 fields: ["url", "alternativeText"],
30 },
31 },
32 },
33 "shared.quote": true,
34 "shared.rich-text": true,
35 "shared.seo": {
36 populate: {
37 shareImage: {
38 fields: ["url", "alternativeText"],
39 },
40 },
41 },
42 "shared.slider": {
43 populate: {
44 files: {
45 fields: ["url", "alternativeText"],
46 },
47 },
48 },
49 },
50 },
51};
52
53export default (config, { strapi }: { strapi: Core.Strapi }) => {
54 // Add your own logic here.
55 return async (ctx, next) => {
56 strapi.log.info("In global-populate middleware.");
57 ctx.query.populate = populate;
58 await next();
59 };
60};
Now, stop the Strapi server and run yarn strapi build
to rebuild your Strapi instance. Once the build is complete, run yarn develop
to restart the Strapi server.
If you go to the route localhost:1337/api/articles
the response returns:
1{
2 "data": [
3 {
4 "id": 6,
5 "documentId": "rhw3yuy75pqbffwzd66t0gas",
6 "title": "A bug is becoming a meme on the internet",
7 "description": "How a bug on MySQL is becoming a meme on the internet",
8 "slug": "a-bug-is-becoming-a-meme-on-the-internet",
9 "createdAt": "2025-03-20T04:01:45.480Z",
10 "updatedAt": "2025-03-20T04:01:45.480Z",
11 "publishedAt": "2025-03-20T05:32:33.297Z",
12 "cover": {
13 "id": 7,
14 "documentId": "v6enttmbyrcb3dr18cotbqy9",
15 "url": "/uploads/a_bug_is_becoming_a_meme_on_the_internet_45047d3322.jpeg",
16 "alternativeText": "An image uploaded to Strapi called a-bug-is-becoming-a-meme-on-the-internet"
17 },
18 "author": {
19 "id": 2,
20 "documentId": "l8658rnyt188wrx20wyr4lm2",
21 "name": "Sarah Baker",
22 "email": "sarahbaker@strapi.io",
23 "createdAt": "2025-03-20T04:01:44.637Z",
24 "updatedAt": "2025-03-20T04:01:44.637Z",
25 "publishedAt": "2025-03-20T04:01:44.637Z",
26 "avatar": {
27 "id": 2,
28 "documentId": "q58qy4o3d2oq3ns00imso4vi",
29 "url": "/uploads/sarahbaker_strapi_49710e917f.jpeg",
30 "alternativeText": "An image uploaded to Strapi called sarahbaker@strapi"
31 }
32 },
33 "category": {
34 "id": 2,
35 "documentId": "t6em1nzl67vuc7lggvckvglm",
36 "name": "tech",
37 "slug": "tech",
38 "description": null,
39 "createdAt": "2025-03-20T04:01:44.345Z",
40 "updatedAt": "2025-03-20T04:01:44.345Z",
41 "publishedAt": "2025-03-20T04:01:44.345Z"
42 },
43 "blocks": [
44 {
45 "__component": "shared.rich-text",
46 "id": 12,
47 "body": "## Probant \n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. \n\n## Abit sua\n\nse Lorem markdownum negat. Argo *saxa* videnda cornuaque hunc qui tanta spes teneas! Obliquis est dicenti est salutat ille tamen iuvenum nostrae dolore. - Colores nocituraque comitata eripiunt - Addit quodcunque solum cui et dextram illis - Nulli meus nec extemplo ille ferebat pressit Se blandita fulvae vox gravem Pittheus cesserunt sanguine herbis tu comitum tenuit. Sui in ruunt; Doridaque maculosae fuissem! Et loqui. "
48 },
49 {
50 "__component": "shared.quote",
51 "id": 7,
52 "title": "Thelonius Monk",
53 "body": "You've got to dig it to dig it, you dig?"
54 },
55 {
56 "__component": "shared.media",
57 "id": 7,
58 "file": {
59 "id": 4,
60 "documentId": "t0l6hazdr8687ssr2iohofpl",
61 "url": "/uploads/coffee_art_fc91419ce6.jpeg",
62 "alternativeText": "An image uploaded to Strapi called coffee-art"
63 }
64 },
65 {
66 "__component": "shared.rich-text",
67 "id": 13,
68 "body": "## Spatiantia astra \n\nFoeda, medio silva *errandum*: onus formam munere. Mutata bibulis est auxiliare arces etiamnunc verbis virgineo Priamidas illa Thescelus, nam fit locis lucis auras. Exitus hospes gratulor ut pondere [speslimite](http://www.curas.io/figuram); quid habent, Avernales faciente de. Pervenit Ino sonabile supplex cognoscenti vires, Bacchumque errat miserarum venandi dignabere dedisti. Discrimina iuncosaque virgaque tot sine superest [fissus](http://quos.org/sitet.aspx). Non color esset potest non sumit, sed vix arserat. Nisi immo silva tantum pectusque quos pennis quisquam artus!"
69 },
70 {
71 "__component": "shared.slider",
72 "id": 6,
73 "files": [
74 {
75 "id": 4,
76 "documentId": "t0l6hazdr8687ssr2iohofpl",
77 "url": "/uploads/coffee_art_fc91419ce6.jpeg",
78 "alternativeText": "An image uploaded to Strapi called coffee-art"
79 },
80 {
81 "id": 5,
82 "documentId": "r5irg1x4d5lquhw8ki16m8fk",
83 "url": "/uploads/coffee_beans_2c502256b4.jpeg",
84 "alternativeText": "An image uploaded to Strapi called coffee-beans"
85 }
86 ]
87 }
88 ]
89 }
90 ],
91 "meta": {
92 "pagination": {
93 "page": 1,
94 "pageSize": 25,
95 "pageCount": 1,
96 "total": 5
97 }
98 }
99}
No query string is needed!
Congrats on Making it to the End!
Here is a recap of what you've just learned:
- How to use
populate=*
. - How to query and filter using LHS Bracket syntax.
- How to use query-string to build custom client-side queries for better re-use.
- How to add custom middlewares to your project.
- How to implement middlewares on an api route.
Project Repo: strapi-middleware-populate-example
Solutions Engineer @ Strapi