Strapi: Customization, customization, customization

Adri Blanco
4 min readMay 26, 2021
Photo by Roman Synkevych on Unsplash

Strapi is a headless CMS that creates an API to access your database with some basic CRUD (Create, Read, Update, Delete) operations. A good option to reduce the backend development work, but with his limitations. After working for a year on real-world projects with Strapi as a backend, we found some problems that were not solved by default. Not a big deal thanks to his customization. Here there are the most important things you should know.

But first…

At any point in these examples, you can access all Strapi functionality. There's a "global variable" that lets you use the controllers of a collection or do queries to the database. Here are some examples:

Notice that, when you access a table that it's related to Strapi plugin functionalities, like the users or the files uploaded, you should add his plugin id to the query. The ids by default are content-manager, content-type-builder, email, upload, and user-permissions.

Lifecycle hooks

Execute code before or after some basic operation occurs. Useful for notifications, calculated values, default values, or creation of another data related.

For example, we want to call another server every time we create/modify some specific field in our database. Go to /api/collection-name/models/collection-name.js

Notify another server after some field is added/updated

Depending on the hook, it could take these attributes:

  • data: The body of the operation.
  • result: The item that is stored after the operation.
  • params: How to identify this item. For example, in update operations, this will be something like { id: 3 }
  • populate: Relations that will replace his id with his content.

Full documentation here

Extend the functionality for the CRUD operations

Strapi may seem like a bad idea when you need more than just CRUD operations, but you can do your business logic by overriding your controllers. For example, you can do a more complex roles system, giving access only to some specific elements, do some validations before creating, or improve the population of the responses.

You can override some operations and others leave it by default in the same collection, just add the one that you need to the file in /api/collection-name/controllers/collection-name.js

Full documentation and the default implementation of the controllers, here.

Notice that the find and the findOne service operations that Strapi do in his default controllers, also could receive an array to populate the output (replace the id of the relation with it's content). But, this will override the default one, so, if you want more, you should add all the relations that you want. Here's an example of how to use this:

Create a new API endpoint

It's pretty common to need some new endpoint that do some business logic over your data, and Strapi have this possibility too. Go to /api/collection-name/config/routes.json and add a new entry to the array like the following:

The image is pretty self explanatory, just a couple of notes.

  • The handler string follows this format: ControllerName.FunctionName. Add that function to the controller file, as we saw in the past section.
  • In the path you can add a wildcard like :id or do validations with a regular expression.
  • If you don't add a config object, it will have public access.
  • If you make a request to this endpoint and returns a 404 Not Found, make sure that your path does not collide with a wildcard. For example, if you push the example to the route array, will not work, because the find definition will response (/items/:id). To solve this, move the definition before it.
  • If you receive a 403 Forbidden error, do a yarn build to recreate the frontend and grant access to this endpoint in the Settings section.

Full documentation, here.


Do unit testing in Strapi…it's a bit of a pain. The main reason is that the Strapi system have to be mounted between each run and it takes fairly 30 seconds to mount and unmount.

To configure the test env, follow the official documentation.


Strapi offers a wide variety of tools to adapt as easy as possible to your needs. This are just the ones that was most used for me, but you can find more info about the rest in the documentation.