Custom API Development with Strapi: Creating Custom Endpoints for Your Frontend Applications

Sachini Dissanayaka
5 min readOct 23, 2023

Strapi is a powerful headless CMS that not only helps you manage content but also allows you to create custom API endpoints. These custom endpoints can be customized to serve data to your frontend applications exactly the way you need it and allow you to define your own routes and logic. In this guide, we will walk you through the process of generating and using a custom API endpoint in Strapi.

Why Custom API Endpoints?

While Strapi comes with a set of built-in API endpoints for content types, there are often cases where you need more control or specific data that isn’t provided by default. This is where custom API endpoints come into play:

  1. Data Transformation: You can customize the data returned by your API to match your frontend’s structure and requirements.
  2. Third-Party Integrations: Connect to external APIs and services, process the data, and serve it to your frontend applications.
  3. Optimized Queries: Create efficient and tailored queries for complex data retrieval.

Prerequisites

Before we get started, make sure you have Strapi installed and have a Strapi project up and running. If you haven’t set up Strapi yet, you can refer to my previous article on “Getting Started with Strapi,” where we covered the process of creating your first content type.

Article Content Type Fields

In this example, we’ll guide you on creating a custom API endpoint called GET /api/get-articles which will provide a simplified list of collection type article.

Final Output 🚀

Creating a Custom API Endpoint

To create our custom API endpoint, we’ll use the strapi generate command. In this example, we'll name our API "get-articles".

npx strapi generate

You can also use yarn if you have it installed globally

yarn strapi generate

Select the “api — Generate a basic API” option from the list provided by the CLI. Name your API “get-articles” and confirm that it’s not for a plugin.

Terminal Output 1
Terminal Output 2

This command will generate the necessary files and structure for your custom API endpoint.

Directory Structure

After generating the API, you will find a new directory named “get-articles” within the src/api folder. Inside this directory, you will find three subdirectories: controllers, routes, and services.

  • Controllers: These contain the logic for your API’s actions. They handle requests and return responses.
  • Routes: Routes define the API endpoints and their associated controller actions.
  • Services: Services are reusable functions used to organize and encapsulate business logic.

Setting Up the Route

In Strapi, routes define how your API will respond to incoming requests. You can find the route configuration in the routes folder within your API's directory. For our "get-articles" API, we'll set up a simple route to handle GET requests at the "/get-articles" endpoint.

Replace the contents of the get-articles.js file in the routes directory with the following code:

module.exports = {
routes: [
{
method: 'GET',
path: '/get-articles',
handler: 'get-articles.getArticles',
config: {
policies: [],
middlewares: [],
},
},
],
};

Controllers and Services

In Strapi, controllers are responsible for handling client requests and invoking the appropriate service functions to perform business logic. Services contain the reusable functions where the actual logic resides.

Replace the code in the get-articles.js file in the controllers directory with the following:

'use strict';

/**
* A set of functions called "actions" for `get-articles`
*/

module.exports = {
getArticles: async (ctx, next) => {
try {
const data = await strapi
.service("api::get-articles.get-articles")
.getArticles();
console.log("Data", data);
ctx.body = data;
} catch (err) {
ctx.badRequest("Get articles controller error", { moreDetails: err });
}
}
};

In the services directory, replace the contents of the get-articles.js file with the following code:

'use strict';

/**
* get-articles service
*/

module.exports = {
getArticles: async () => {
try {
// Fetching data
const entries = await strapi.entityService.findMany(
"api::article.article",
{
fields: ["id", "Title", "Content", "createdAt"],
populate: {
Author: {
fields: ["username", "email"],
},
Category: {
fields: ["name"],
},
},
}
);

// Reduce the data to the format we want to return
let entriesReduced;
if (entries && Array.isArray(entries)) {
entriesReduced = entries.reduce((acc, item) => {
acc = acc || [];
acc.push({
id: item?.id,
title: item.Title || "",
category: item.Category.name || "",
publishedDate: new Date(item.createdAt).toDateString() || "",
authorName: item.Author?.username || "",
authorEmail: item.Author?.email || "",
content: item.Content || ""
});
return acc;
}, []);
}

// Return the reduced data
return entriesReduced;
} catch (err) {
return err;
}
},
};

Setting Permissions

By default, custom API endpoints may not be accessible to the public. To control access, you can set permissions for your API in the Strapi dashboard.

  1. Navigate to “Settings” > “Roles” > “Authenticated.”
  2. For public access, visit “Settings” > “Roles” > “Public.”

In the “Get-articles” route permissions, select the necessary access permissions.

Note: Ensure that you’ve properly configured access permissions for “Article,” “Category,” and “Users-Permissions” (user) to retrieve the correct data. Otherwise, you might not see all the fields.

Access Permissions 🔐

Now, your custom API is ready for use. You can access it by making a GET request to http://localhost:1337/api/get-articles using a tool like Postman or simply by opening it in your browser.

Conclusion

By following the steps outlined in this guide, you can create custom API endpoints that serve data exactly as your frontend applications require. This flexibility empowers you to build dynamic and feature-rich applications with ease.

Experiment with your custom API endpoints and enjoy the power of tailored data delivery to your frontend applications. Happy custom API development with Strapi! 😊

--

--

Sachini Dissanayaka
Sachini Dissanayaka

Written by Sachini Dissanayaka

SDE | Master's student at the University of York in Computer Science with Artificial Intelligence

No responses yet