Strapi
Published in

Strapi

Route-Based Middleware to Handle Default Population Query Logic

Learn how to set the default “populate” options via route middleware in the backend.

What is Route Middleware?

Sample Content Structure

sample content structure

The Problem

// localhost:1337/api/blog-posts
{
"data": [
{
"id": 1,
"attributes": {
"title": "Test Blog Post",
"body": "Test blog content",
"slug": "test-blog-post",
"createdAt": "2022-08-09T18:45:19.012Z",
"updatedAt": "2022-08-09T18:45:21.710Z",
"publishedAt": "2022-08-09T18:45:21.707Z"
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}

Populate = *

// localhost:1337/api/blog-posts?populate=*
{
"data": [
{
"id": 1,
"attributes": {
"title": "Test Blog Post",
"body": "Test blog content",
"slug": "test-blog-post",
"createdAt": "2022-08-09T18:45:19.012Z",
"updatedAt": "2022-08-09T19:22:39.637Z",
"publishedAt": "2022-08-09T18:45:21.707Z",
"heroImage": {
"data": {
"id": 1,
"attributes": {
"name": "test_cat.jpeg",
"alternativeText": "test_cat.jpeg",
"caption": "test_cat.jpeg",
"width": 500,
"height": 500,
"formats": {
"thumbnail": {
"name": "thumbnail_test_cat.jpeg",
"hash": "thumbnail_test_cat_2bdaa9fbe9",
"ext": ".jpeg",
"mime": "image/jpeg",
"path": null,
"width": 156,
"height": 156,
"size": 5.01,
"url": "/uploads/thumbnail_test_cat_2bdaa9fbe9.jpeg"
}
},
"hash": "test_cat_2bdaa9fbe9",
"ext": ".jpeg",
"mime": "image/jpeg",
"size": 21.78,
"url": "/uploads/test_cat_2bdaa9fbe9.jpeg",
"previewUrl": null,
"provider": "local",
"provider_metadata": null,
"createdAt": "2022-08-09T19:06:25.220Z",
"updatedAt": "2022-08-09T19:06:25.220Z"
}
}
},
"authors": {
"data": {
"id": 1,
"attributes": {
"username": "testUser",
"email": "test@test.com",
"provider": "local",
"confirmed": true,
"blocked": false,
"createdAt": "2022-08-09T19:07:03.325Z",
"updatedAt": "2022-08-09T19:07:03.325Z"
}
}
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}

Getting Granular

localhost:1337/api/blog-posts?populate[heroImage][fields]
[0]=name&populate[heroImage][fields]
[1]=alternativeText&populate[heroImage][fields]
[2]=caption&populate[heroImage][fields]
[3]=url&populate[authors][fields]
[0]=username&populate[authors][populate][role][fields]
[0]=name

Enter… Query-String

const qs = require('qs')
const query = qs.stringify(
{
populate: {
heroImage: {
fields: ['name', 'alternativeText', 'caption', 'url'],
},
authors: {
fields: ['username'],
populate: {
role: {
fields: ['name'],
},
},
},
},
},
{
encodeValuesOnly: true, // prettify URL
}
)
// `localhost:1337/api/blog-posts?${query}`
{
"data": [
{
"id": 1,
"attributes": {
"title": "Test Blog Post",
"body": "Test blog content",
"slug": "test-blog-post",
"createdAt": "2022-08-09T18:45:19.012Z",
"updatedAt": "2022-08-09T19:22:39.637Z",
"publishedAt": "2022-08-09T18:45:21.707Z",
"heroImage": {
"data": {
"id": 1,
"attributes": {
"name": "test_cat.jpeg",
"alternativeText": "test_cat.jpeg",
"caption": "test_cat.jpeg",
"url": "/uploads/test_cat_2bdaa9fbe9.jpeg"
}
}
},
"authors": {
"data": {
"id": 1,
"attributes": {
"username": "testUser"
}
}
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}

Query Logic in Middleware

Initializing the New Middleware

yarn strapi generate
middleware
run middleware
select route
'use strict'

/**
* `test` middleware.
*/

module.exports = (config, { strapi }) => {
// Add your own logic here.
return async (ctx, next) => {
strapi.log.info('In test middleware.')

await next()
}
}

Enable Middleware on Route

'use strict'

/**
* blog-post router.
*/

const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::blog-post.blog-post')
'use strict'

/**
* blog-post router.
*/

const { createCoreRouter } = require('@strapi/strapi').factories

module.exports = createCoreRouter('api::blog-post.blog-post', {
config: {
find: {
middlewares: ['api::blog-post.test'],
},
},
})
yarn strapi middlewares:list
list of middleware

Adding Logic to the Middleware

// src > api > blog-post > middlewares > test.js

module.exports = (config, { strapi }) => {
// This is where we add our middleware logic
return async (ctx, next) => {
ctx.query.populate = {
heroImage: {
fields: ['name', 'alternativeText', 'caption', 'url'],
},
authors: {
fields: ['username'],
populate: {
role: {
fields: ['name'],
},
},
},
}

await next()
}
}
{
"data": [
{
"id": 1,
"attributes": {
"title": "Test Blog Post",
"body": "Test blog content",
"slug": "test-blog-post",
"createdAt": "2022-08-09T18:45:19.012Z",
"updatedAt": "2022-08-09T19:22:39.637Z",
"publishedAt": "2022-08-09T18:45:21.707Z",
"heroImage": {
"data": {
"id": 1,
"attributes": {
"name": "test_cat.jpeg",
"alternativeText": "test_cat.jpeg",
"caption": "test_cat.jpeg",
"url": "/uploads/test_cat_2bdaa9fbe9.jpeg"
}
}
},
"authors": {
"data": {
"id": 1,
"attributes": {
"username": "testUser"
}
}
}
}
}
],
"meta": {
"pagination": {
"page": 1,
"pageSize": 25,
"pageCount": 1,
"total": 1
}
}
}

Congrats on Making it to the End!

--

--

Strapi is the leading open-source headless CMS. It’s 100% Javascript, fully customizable and developer-first. Unleash your content with Strapi.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store