Server API for plugins
A Strapi plugin can interact with the backend or the frontend of the Strapi application. The Server API is about the backend part.
Creating and using a plugin interacting with the Server API consists of 2 steps:
- Declare and export the plugin interface within the
strapi-server.js
entry file - Use the exported interface
Entry file
To tap into the Server API, create a strapi-server.js
file at the root of the plugin package folder. This file exports the required interface, with the following parameters available:
Parameter type | Available parameters |
---|---|
Lifecycle functions | |
Configuration | |
Backend customizations |
Lifecycle functions
register()
This function is called to load the plugin, before the application is bootstrapped, in order to register permissions, the server part of custom fields, or database migrations.
Type: Function
Example:
module.exports = () => ({
register({ strapi }) {
// execute some register code
},
});
bootstrap()
The bootstrap function is called right after the plugin has registered.
Type: Function
Example:
module.exports = () => ({
bootstrap({ strapi }) {
// execute some bootstrap code
},
});
destroy()
The destroy lifecycle function is called to cleanup the plugin (close connections, remove listeners, etc.) when the Strapi instance is destroyed.
Type: Function
Example:
module.exports = () => ({
destroy({ strapi }) {
// execute some destroy code
},
});
Configuration
config
stores the default plugin configuration.
Type: Object
Parameter | Type | Description |
---|---|---|
default | Object, or Function that returns an Object | Default plugin configuration, merged with the user configuration |
validator | Function |
|
Example:
const config = require('./config');
module.exports = () => ({
config: {
default: ({ env }) => ({ optionA: true }),
validator: (config) => {
if (typeof config.optionA !== 'boolean') {
throw new Error('optionA has to be a boolean');
}
},
},
});
Once defined, the configuration can be accessed:
- with
strapi.plugin('plugin-name').config('some-key')
for a specific configuration property, - or with
strapi.config.get('plugin.plugin-name')
for the whole configuration object.
Cron
The cron
object allows you to add cron jobs to the Strapi instance.
module.exports = () => ({
bootstrap({ strapi }) {
strapi.cron.add({
// runs every second
myJob: {
task: ({ strapi }) => {
console.log("hello from plugin");
},
options: {
rule: "* * * * * *",
},
},
});
},
});
To remove a CRON job you can call the remove function on the strapi.cron
object and pass in the key corresponding to the CRON job you want to remove.
Cron jobs that are using the key as the rule can not be removed.
strapi.cron.remove("myJob");
List cron jobs
To list all the cron jobs that are currently running you can call the jobs
array on the strapi.cron
object.
strapi.cron.jobs
Backend customization
Content-types
An object with the content-types the plugin provides.
Type: Object
Content-Types keys in the contentTypes
object should re-use the singularName
defined in the info
key of the schema.
Example:
"use strict";
module.exports = require('./server');
const contentTypes = require('./content-types');
module.exports = () => ({
contentTypes,
});
const contentTypeA = require('./content-type-a');
const contentTypeB = require('./content-type-b');
module.exports = {
'content-type-a': { schema: contentTypeA }, // should re-use the singularName of the content-type
'content-type-b': { schema: contentTypeB },
};
module.exports = {
kind: 'collectionType',
collectionName: 'content-type',
info: {
singularName: 'content-type-a', // kebab-case mandatory
pluralName: 'content-type-as', // kebab-case mandatory
displayName: 'Content Type A',
description: 'A regular content-type',
},
options: {
draftAndPublish: true,
},
pluginOptions: {
'content-manager': {
visible: false,
},
'content-type-builder': {
visible: false,
}
},
attributes: {
name: {
type: 'string',
min: 1,
max: 50,
configurable: false,
},
}
};
Routes
An array of routes configuration.
Type: Object[]
Example:
"use strict";
module.exports = require('./server');
const routes = require('./routes');
module.exports = () => ({
routes,
type: 'content-api', // can also be 'admin' depending on the type of route
});
module.exports = [
{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['policyName'],
},
},
];
Controllers
An object with the controllers the plugin provides.
Type: Object
Example:
"use strict";
module.exports = require('./server');
const controllers = require('./controllers');
module.exports = () => ({
controllers,
});
const controllerA = require('./controller-a');
const controllerB = require('./controller-b');
module.exports = {
controllerA,
controllerB,
};
module.exports = ({ strapi }) => ({
doSomething(ctx) {
ctx.body = { message: 'HelloWorld' };
},
});
Services
An object with the services the plugin provides.
Services should be functions taking strapi
as a parameter.
Type: Object
Example:
"use strict";
module.exports = require('./server');
const services = require('./services');
module.exports = () => ({
services,
});
const serviceA = require('./service-a');
const serviceB = require('./service-b');
module.exports = {
serviceA,
serviceB,
};
module.exports = ({ strapi }) => ({
someFunction() {
return [1, 2, 3];
},
});
Policies
An object with the policies the plugin provides.
Type: Object
Example:
"use strict";
module.exports = require('./server');
const policies = require('./policies');
module.exports = () => ({
policies,
});
const policyA = require('./policy-a');
const policyB = require('./policy-b');
module.exports = {
policyA,
policyB,
};
module.exports = (policyContext, config, { strapi }) => {
if (ctx.state.user && ctx.state.user.isActive) {
return true;
}
return false;
};
Middlewares
An object with the middlewares the plugin provides.
Type: Object
Example:
"use strict";
module.exports = require('./server');
const middlewares = require('./middlewares');
module.exports = () => ({
middlewares,
});
const middlewareA = require('./middleware-a');
const middlewareB = require('./middleware-b');
module.exports = {
middlewareA,
middlewareB,
};
module.exports = (options, { strapi }) => {
return async (ctx, next) => {
const start = Date.now();
await next();
const delta = Math.ceil(Date.now() - start);
strapi.log.http(`${ctx.method} ${ctx.url} (${delta} ms) ${ctx.status}`);
};
};
Usage
Once a plugin is exported and loaded into Strapi, its features are accessible in the code through getters. The Strapi instance (strapi
) exposes top-level getters and global getters.
While top-level getters imply chaining functions, global getters are syntactic sugar that allows direct access using a feature's uid:
// Access an API or a plugin controller using a top-level getter
strapi.api['api-name'].controller('controller-name')
strapi.plugin('plugin-name').controller('controller-name')
// Access an API or a plugin controller using a global getter
strapi.controller('api::api-name.controller-name')
strapi.controller('plugin::plugin-name.controller-name')
Top-level getter syntax examples
strapi.plugin('plugin-name').config
strapi.plugin('plugin-name').routes
strapi.plugin('plugin-name').controller('controller-name')
strapi.plugin('plugin-name').service('service-name')
strapi.plugin('plugin-name').contentType('content-type-name')
strapi.plugin('plugin-name').policy('policy-name')
strapi.plugin('plugin-name').middleware('middleware-name')
Global getter syntax examples
strapi.controller('plugin::plugin-name.controller-name');
strapi.service('plugin::plugin-name.service-name');
strapi.contentType('plugin::plugin-name.content-type-name');
strapi.policy('plugin::plugin-name.policy-name');
strapi.middleware('plugin::plugin-name.middleware-name');
To interact with the content-types, use the Entity Service API.