Services
Services are a set of reusable functions. They are particularly useful to respect the "donβt repeat yourself" (DRY) programming concept and to simplify controllers logic.

Implementationβ
Services can be generated or added manually. Strapi provides a createCoreService
factory function that automatically generates core services and allows building custom ones or extend or replace the generated services.
Adding a new serviceβ
A new service can be implemented:
- with the interactive CLI command
strapi generate
- or manually by creating a JavaScript file in the appropriate folder (see project structure):
./src/api/[api-name]/services/
for API services- or
./src/plugins/[plugin-name]/services/
for plugin services.
To manually create a service, export a factory function that returns the service implementation (i.e. an object with methods). This factory function receives the strapi
instance:
- JavaScript
- TypeScript
const { createCoreService } = require('@strapi/strapi').factories;
module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => ({
// Method 1: Creating an entirely new custom service
async exampleService(...args) {
let response = { okay: true }
if (response.okay === false) {
return { response, error: true }
}
return response
},
// Method 2: Wrapping a core service (leaves core logic in place)
async find(...args) {
// Calling the default core controller
const { results, pagination } = await super.find(...args);
// some custom logic
results.forEach(result => {
result.counter = 1;
});
return { results, pagination };
},
// Method 3: Replacing a core service
async findOne(entityId, params = {}) {
return strapi.entityService.findOne('api::restaurant.restaurant', entityId, this.getFetchParams(params));
}
}));
import { factories } from '@strapi/strapi';
export default factories.createCoreService('api::restaurant.restaurant', ({ strapi }) => ({
// Method 1: Creating an entirely custom service
async exampleService(...args) {
let response = { okay: true }
if (response.okay === false) {
return { response, error: true }
}
return response
},
// Method 2: Wrapping a core service (leaves core logic in place)
async find(...args) {
// Calling the default core controller
const { results, pagination } = await super.find(...args);
// some custom logic
results.forEach(result => {
result.counter = 1;
});
return { results, pagination };
},
// Method 3: Replacing a core service
async findOne(entityId, params = {}) {
return strapi.entityService.findOne('api::restaurant.restaurant', entityId, this.getFetchParams(params));
}
}));
To get started creating your own services, see Strapi's built-in functions in the Entity Service API documentation.
Example of a custom email service (using Nodemailer)
When a new content-type is created, Strapi builds a generic service with placeholder code, ready to be customized.
To see a possible advanced usage for custom services, read the services and controllers page of the backend customization examples cookbook.
Extending core servicesβ
Core services are created for each content-type and could be used by controllers to execute reusable logic through a Strapi project. Core services can be customized to implement your own logic. The following code examples should help you get started.
A core service can be replaced entirely by creating a custom service and naming it the same as the core service (e.g. find
, findOne
, create
, update
, or delete
).
Collection type examples
Single type examples
The find()
method from core services can use both types of pagination, by page of by offset (see REST API).
Usageβ
Once a service is created, it's accessible from controllers or from other services:
// access an API service
strapi.service('api::apiName.serviceName').FunctionName();
// access a plugin service
strapi.service('plugin::pluginName.serviceName').FunctionName();
In the syntax examples above, serviceName
is the name of the service file for API services or the name used to export the service file to services/index.js
for plugin services.
To list all the available services, run yarn strapi services:list
.