How to Create a Custom API Endpoint in Strapi?
Strapi offers a collection of potent APIs that enable programmers to design unique API endpoints. We'll be building a custom API endpoint from scratch in this article.
Prerequisites
Before you can jump into this content, you need to have the following:
- Basic knowledge of JavaScript
- Basic understanding of Strapi - get started here
Installing Strapi
The following command will install a new Strapi instance with some preset configurations and data.
npx create-strapi-app plugins-v4-1 --template corporate
Please, See the create-strapi-app node package page to learn about the various Strapi installation options.
You must select Custom as the installation type if you are using the --template corporate flag. Set the default database to sqlite.
? Choose your installation type Custom (manual settings)
? Choose your default database client sqlite
? Filename: .tmp/data.db
Ensure that the current directory in the terminal is the project directory. Fire up the development server.
cd plugins-v4-1/
yarn develop --watch-admin
The front-end development server and autoReload are both enabled when the application is started using the --watch-admin flag. It enables programmers to alter the administrative panel.
The browser automatically creates a new tab after the installation is finished. Visit http://localhost:8000/admin/
if you need to.
In the event that port 8000
is already in use by another process, please verify the alternative port listed in the CLI output. Typically, the value would be 8080
.
Fill out the form to add the application's initial administrator user.
The front-end development server and autoReload are both enabled when the application is started using the --watch-admin flag. It enables programmers to alter the administrative panel.
The corporate template automatically creates a single type, a collection of types, and components.
Components:
- User
- Page
- Lead From submission
Single Types:
- Global
Components:
A lot of components for Elements, Layout, Links, Meta, and Sections. The template also provides us with some pre-filled data to play around with. All of these happen just by providing the --template corporate
flag at the time of Strapi installation.
Setting-up a Use Case
We have a pre-populated collection-type page with some information.
Strapi delivers the entire page, filled with all of its components and dynamic-zone component data, in response to a get request to http://localhost:1337/api/pages?populate=*
.
In order to offer a condensed summary of the pages, a custom API Endpoint GET /api/pages-report
must be created.
[
{ "id": 1, "name": "Home", "metaTitle": "Strapi corporate site starter" },
{ "id": 2, "name": "Pricingg", "metaTitle": "Pricing" },
{ "id": 3, "name": "Secret", "metaTitle": "Secret page" },
{ "id": 4, "name": "Contact", "metaTitle": "Contact" }
]
Exactly this is what we are going to construct in this post.
Generating a Basic API
A CLI session that is interactive is launched by the npx strapi generate
command. If your system has yarn and strapi
installed globally, you are welcome to use yarn
in place of the npx
command.
You can choose from the choices listed below. Please take note of the word "report" in the name of our API pages.
Within the src/api
directory, this command creates a directory called pages-reports. Controllers
, routes
, and services
are three directories that are part of the pages-report
.
Routes
Routes manage requests sent to Strapi on any URL. According to the REST API specification, Strapi automatically constructs routes for every content type. It is possible to add and configure routes. Once a route is established, using it causes a controller to run some logic.
The following lines of code should be added to src/api/pages-report/routes/pages-report.js
.
module.exports = {
routes: [
{
method: 'GET',
path: '/pages-report',
handler: 'pages-report.findAll',
config: {
policies: [],
middlewares: [],
},
},
],
};
Controllers vs Services
A collection of methods called actions are contained in controllers, which are JavaScript files that are accessed by the client in accordance with the desired route. The action executes the business logic code and provides the response whenever a client requests the route. The C in the model-view-controller (MVC) pattern is represented by the controller. Most of a project's business logic will be found in the controllers. However, when a controller's logic grows more intricate, it's a good idea to use services to divide the code into sections that can be reused.
A set of reusable operations make up services. They are very helpful for simplifying controller logic and adhering to the DRY (don't repeat yourself) programming principle.
Creating a Service
Services essentially don't know about the request and response ctx objects of Koa. It is planned for this function to be adaptable and reusable.
Replace the following lines of code in /src/api/pages-report/services/pages-report.js
:
'use strict';
module.exports = {
pagesReport: async () => {
try {
// fetching the data
// we dont really need contentSections for this example.
// its kept here, just for your reference
const entries = await strapi.entityService.findMany('api::page.page', {
fields: ['id', 'shortName'],
populate: {
metadata: {
fields: ['metaTitle']
},
contentSections: {
populate: '*'
}
}
});
// reducing the data to a simple array
let entriesReduced;
if (entries && Array.isArray(entries)) {
entriesReduced = entries.reduce((acc, item) => {
acc = acc || [];
console.log(acc);
acc.push({
id: item.id,
name: item.shortName || '',
metaTitle: item.metadata?.metaTitle || ''
});
return acc;
}, [])
// returning the reduced data
return entriesReduced;
}
} catch (err) {
return err;
}
}
}
To fetch all pages, we are using the Entity Service API for Strapi in this code. Read the documentation for the Populating the Entity Service API to find out more about the flexible ways to populate the response.
The following data will be returned by the pagesReport service:
[
{ "id": 1, "name": "Home", "metaTitle": "Strapi corporate site starter" },
{ "id": 2, "name": "Pricingg", "metaTitle": "Pricing" },
{ "id": 3, "name": "Secret", "metaTitle": "Secret page" },
{ "id": 4, "name": "Contact", "metaTitle": "Contact" }
]
Once a service is created, it's accessible from controllers or from other services:
// access an API service
strapi.service('api::apiName.serviceName');
// access a plugin service
strapi.service('plugin::pluginName.serviceName');
Controllers and services can log the list of available services:
console.log('strapi.services ', strapi.services);
console.log('pages-report', strapi.service('api::pages-report.pages-report'));
Creating a Controller
A controller function is in charge of invoking our service upon request and returning the results to the response
because it has direct access to the Koa's ctx.
Replace the following lines of code in src/api/pages-report/controllers/pages-report.js
:
'use strict';
module.exports = {
async findAll(ctx, next) {
try {
const data = await strapi.service('api::pages-report.pages-report').pagesReport();
ctx.body = data;
} catch (err) {
ctx.badRequest('Page report controller error', { moreDetails: err })
}
}
};
Setting Permissions for the API
For the use case, it is all the code that is needed. /api/pages-report
should receive a get request. A 403 error will most likely appear.
Please navigate to Setting > Roles > Public on the Strapi dashboard to enable public access to the end-point. Please review the results for the pages-report route before pressing the save button.
Currently, the public can use the customised API:
To obtain and filter the results for this article, we made use of Strapi's Entity Service API. It's not the only method available to complete this assignment. Using the Rest API, Query Engine API, and GraphQL API, users of Strapi can fetch and filter results.
The layer that manages Strapi's intricate data structures, such as components and dynamic zones, leverages the Query Engine API to power database operations. It is therefore a logical option for this use scenario. Using the filtering and advanced population techniques of the Entity Service API, we can adapt our example to meet our needs.
Top comments (2)
Nice
Thank you bro