插件的服务器 API
¥Server API for plugins
Strapi plugin 可以与 Strapi 应用的后端和 前端 交互。服务器 API 与后端部分有关,即插件如何与 Strapi 应用的服务器部分交互。
¥A Strapi plugin can interact with both the back end and the front end of a Strapi application. The Server API is about the back-end part, i.e. how the plugin interacts with the server part of a Strapi application.
服务器 API 包括:
¥The Server API includes:
-
导出所需接口的 入口文件,
¥an entry file which export the required interface,
-
configuration API,
-
和 自定义后端服务器的所有元素 的能力。
¥and the ability to customize all elements of the back-end server.
一旦你声明并导出了插件接口,你将能够 使用插件接口。
¥Once you have declared and exported the plugin interface, you will be able to use the plugin interface.
插件服务器部分的整个代码可以存在于 /server/src/index.ts|js
文件中。但是,建议将代码拆分到不同的文件夹中,就像插件 SDK 创建的 structure 一样。
¥The whole code for the server part of your plugin could live in the /server/src/index.ts|js
file. However, it's recommended to split the code into different folders, just like the structure created by the Plugin SDK.
录入文件
¥Entry file
插件文件夹根目录下的 /src/server/index.js
文件导出所需的接口,并提供以下参数:
¥The /src/server/index.js
file at the root of the plugin folder exports the required interface, with the following parameters available:
参数类型 | 可用参数 |
---|---|
生命周期函数 | |
配置 | |
后端定制 |
生命周期函数
¥Lifecycle functions
register()
在应用为 bootstrapped 之前调用此函数来加载插件,以便注册 permissions、自定义字段 的服务器部分或数据库迁移。
¥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.
类型:Function
¥Type: Function
示例:
¥Example:
- JavaScript
- TypeScript
'use strict';
const register = ({ strapi }) => {
// execute some register code
};
module.exports = register;
import type { Core } from '@strapi/strapi';
const register = ({ strapi }: { strapi: Core.Strapi }) => {
// execute some register code
};
export default register;
bootstrap()
bootstrap 函数在插件有 registered 之后立即调用。
¥The bootstrap function is called right after the plugin has registered.
类型:Function
¥Type: Function
示例:
¥Example:
- JavaScript
- TypeScript
'use strict';
const bootstrap = ({ strapi }) => {
// execute some bootstrap code
};
module.exports = bootstrap;
import type { Core } from '@strapi/strapi';
const bootstrap = ({ strapi }: { strapi: Core.Strapi }) => {
// execute some bootstrap code
};
export default bootstrap;
destroy()
当 Strapi 实例被销毁时,会调用 destroy 生命周期函数来清理插件(关闭连接、删除监听器等)。
¥The destroy lifecycle function is called to cleanup the plugin (close connections, remove listeners, etc.) when the Strapi instance is destroyed.
类型:Function
¥Type: Function
示例:
¥Example:
- JavaScript
- TypeScript
'use strict';
const destroy = ({ strapi }) => {
// execute some destroy code
};
module.exports = destroy;
import type { Core } from '@strapi/strapi';
const destroy = ({ strapi }: { strapi: Core.Strapi }) => {
// destroy phase
};
export default destroy;
配置
¥Configuration
config
存储默认的插件配置。它加载并验证用户在 ./config/plugins.js
配置文件 中输入的配置。
¥config
stores the default plugin configuration. It loads and validates the configuration inputted from the user within the ./config/plugins.js
configuration file.
类型:Object
¥Type: Object
范围 | 类型 | 描述 |
---|---|---|
default | 对象或返回对象的函数 | 默认插件配置,与用户配置合并 |
validator | 函数 |
示例:
¥Example:
- JavaScript
- TypeScript
module.exports = {
default: ({ env }) => ({ optionA: true }),
validator: (config) => {
if (typeof config.optionA !== 'boolean') {
throw new Error('optionA has to be a boolean');
}
},
};
export default {
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:
-
strapi.plugin('plugin-name').config('some-key')
表示特定配置属性,¥with
strapi.plugin('plugin-name').config('some-key')
for a specific configuration property, -
或使用
strapi.config.get('plugin.plugin-name')
表示整个配置对象。¥or with
strapi.config.get('plugin.plugin-name')
for the whole configuration object.
运行 yarn strapi console
或 npm run strapi console
以访问实时控制台中的 Strapi 对象。
¥Run yarn strapi console
or npm run strapi console
to access the strapi object in a live console.
后端定制
¥Backend customization
Strapi 后端服务器的所有元素都可以使用服务器 API 通过插件进行自定义。
¥All elements of the back-end server of Strapi can be customized through a plugin using the Server API.
为了更好地理解本节,请确保你已阅读 Strapi 应用的 后端定制 文档。
¥To better understand this section, ensure you have read through the back-end customization documentation of a Strapi application.
内容类型
¥Content-types
插件提供的具有 content-types 的对象。
¥An object with the content-types the plugin provides.
类型:Object
¥Type: Object
contentTypes
对象中的 Content-Types 键应重新使用架构的 info
键中定义的 singularName
。
¥Content-Types keys in the contentTypes
object should re-use the singularName
defined in the info
key of the schema.
示例:
¥Example:
- JavaScript
- TypeScript
'use strict';
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,
},
}
};
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 },
};
export default {
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
routes 配置的数组。
¥An array of routes configuration.
类型:Object[]
¥Type: Object[]
示例:
¥Examples:
- Content API routes only
- Content API and admin routes
- JavaScript
- TypeScript
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'],
},
},
];
const routes = require('./routes');
export default {
routes,
type: 'content-api', // can also be 'admin' depending on the type of route
};
export default [
{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['policyName'],
},
},
];
如果你需要不同的策略,也可以组合管理和内容 API 路由:
¥It is also possible to combine both admin and Content API routes if you need different policies on these:
- JavaScript
- TypeScript
module.exports = {
admin: require('./admin'),
'content-api': require('./content-api'),
};
module.exports = {
type: 'admin',
routes: [{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['policyName'],
},
}],
};
module.exports = {
type: 'content-api',
routes: [{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['differentPolicyName'],
},
}],
};
export default {
admin: require('./admin'),
'content-api': require('./content-api'),
};
export default {
type: 'admin',
routes: [{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['policyName'],
},
}],
};
export default {
type: 'content-api',
routes: [{
method: 'GET',
path: '/model',
handler: 'controllerName.action',
config: {
policies: ['differentPolicyName'],
},
}],
};
控制器
¥Controllers
插件提供的具有 controllers 的对象。
¥An object with the controllers the plugin provides.
类型:Object
¥Type: Object
示例:
¥Example:
- JavaScript
- TypeScript
//…
const controllers = require('./controllers');
//…
module.exports = () => ({
//…
controllers,
//…
});
const controllerA = require('./controller-a');
const controllerB = require('./controller-b');
module.exports = {
controllerA,
controllerB,
};
'use strict';
const controllerA = ({ strapi }) => ({
index(ctx) {
ctx.body = strapi
.plugin('my-strapi-plugin')
// the name of the service file & the method.
.service('service')
.getWelcomeMessage();
},
});
module.exports = controllerA;
import controllers from './controllers';
module.exports = () => ({
controllers,
});
import controllerA from './controller-a';
import controllerB from './controller-b';
export default {
controllerA,
controllerB,
};
import type { Core } from '@strapi/strapi';
const controllerA = ({ strapi }: { strapi: Core.Strapi }) => ({
index(ctx) {
ctx.body = strapi
.plugin('my-strapi-plugin')
// the name of the service file & the method.
.service('service')
.getWelcomeMessage();
},
});
export default controllerA;
服务
¥Services
插件提供的具有 services 的对象。
¥An object with the services the plugin provides.
服务应该是以 strapi
作为参数的函数。
¥Services should be functions taking strapi
as a parameter.
类型:Object
¥Type: Object
示例:
¥Example:
- JavaScript
- TypeScript
// …
const services = require('./services');
// …
module.exports = () => ({
// …
services,
// …
});
const serviceA = require('./service-a');
const serviceB = require('./service-b');
module.exports = {
serviceA,
serviceB,
};
'use strict';
const service = ({ strapi }) => ({
getWelcomeMessage() {
return 'Welcome to Strapi 🚀';
},
});
module.exports = service;
// …
import services from './services';
// …
export default {
// …
services,
// …
};
import serviceA from './service-a';
import serviceB from './service-b';
export default {
serviceA,
serviceB,
};
import type { Core } from '@strapi/strapi';
const serviceA = ({ strapi }: { strapi: Core.Strapi }) => ({
getWelcomeMessage() {
return 'Welcome to Strapi 🚀';
},
});
export default serviceA;
政策
¥Policies
插件提供的具有 policies 的对象。
¥An object with the policies the plugin provides.
类型:Object
¥Type: Object
示例:
¥Example:
- JavaScript
- TypeScript
"use strict";
//…
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;
};
//…
import policies from './policies';
//…
module.exports = {
//…
policies,
//…
};
import policyA from './policy-a';
import policyB from './policy-b';
export default {
policyA,
policyB,
};
export default (policyContext, config, { strapi }) => {
if (ctx.state.user && ctx.state.user.isActive) {
return true;
}
return false;
};
中间件
¥Middlewares
插件提供的具有 middlewares 的对象。
¥An object with the middlewares the plugin provides.
类型:Object
¥Type: Object
示例:
¥Example:
- JavaScript
- TypeScript
/**
* The your-middleware.js file
* declares a basic middleware function and exports it.
*/
'use strict';
module.exports = async (ctx, next) => {
console.log("your custom logic")
await next();
}
/**
* The middleware function previously created
* is imported from its file and
* exported by the middlewares index.
*/
'use strict';
const yourMiddleware = require('./your-middleware');
module.exports = {
yourMiddleware
};
/**
* The middleware is called from
* the plugin's register lifecycle function.
*/
'use strict';
const middlewares = require('./middlewares');
module.exports = ({ strapi }) => {
strapi.server.use(middlewares.yourMiddleware);
};
/**
* The your-middleware.js file
* declares a basic middleware function and exports it.
*/
const middleware = async (ctx, next) => {
console.log("your custom logic")
await next();
}
export default middleware;
/**
* The middleware function previously created
* is imported from its file and
* exported by the middlewares index.
*/
import yourMiddleware from 'your-middleware';
export default {
yourMiddleware
};
/**
* The middleware is called from
* the plugin's register lifecycle function.
*/
import type { Core } from '@strapi/strapi';
import middlewares from './middlewares';
export default ({ strapi }: { strapi: Core.Strapi }) => {
strapi.server.use(middlewares.yourMiddleware);
};
用法
¥Usage
一旦插件导出并加载到 Strapi 中,就可以通过 getter 在代码中访问其功能。Strapi 实例 (strapi
) 公开顶层 getter 和全局 getter:
¥Once a plugin is exported and loaded into Strapi, its features are accessible in the code through getters. The Strapi instance (strapi
) exposes both top-level getters and global getters:
-
顶层获取器意味着链接函数
(例如,strapi.plugin('the-plugin-name').controller('the-controller-name'
),¥top-level getters imply chaining functions
(e.g.,strapi.plugin('the-plugin-name').controller('the-controller-name'
), -
全局 getter 是语法糖,允许使用功能的 uid
(例如strapi.controller('plugin::plugin-name.controller-name')
)直接访问。¥global getters are syntactic sugar that allows direct access using a feature's uid
(e.g.,strapi.controller('plugin::plugin-name.controller-name')
).
// 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');