文档服务 API:中间件
🌐 Document Service API: Middlewares
文档服务 API 提供了通过中间件扩展其行为的能力。
🌐 The Document Service API offers the ability to extend its behavior thanks to middlewares.
文档服务中间件允许你在方法运行之前和/或之后执行操作。
🌐 Document Service middlewares allow you to perform actions before and/or after a method runs.

注册中间件
🌐 Registering a middleware
语法:strapi.documents.use(middleware)
🌐 Syntax: strapi.documents.use(middleware)
参数
🌐 Parameters
中间件是一种接收上下文和下一个函数的函数。
🌐 A middleware is a function that receives a context and a next function.
语法:(context, next) => ReturnType<typeof next>
🌐 Syntax: (context, next) => ReturnType<typeof next>
| 参数 | 描述 | 类型 ||-----------|---------------------------------------|------------|| context | 中间件上下文 | Context || next | 调用堆栈中的下一个中间件 | function |
context
| 参数 | 描述 | 类型 ||---------------|--------------------------------------------------------------------------------------|---------------|| action | 正在运行的方法(查看可用方 法) | string || params | 方法参数(查看可用方法) | Object || uid | 内容类型唯一标识 | string || contentType | 内容类型 | ContentType |
示例:
以下示例显示了根据调用的方法,context 可能包含的内容:
🌐 The following examples show what context might include depending on the method called:
- findOne
- findMany
- create
- update
- delete
{
uid: "api::restaurant.restaurant",
contentType: {
kind: "collectionType",
collectionName: "restaurants",
info: {
singularName: "restaurant",
pluralName: "restaurants",
displayName: "restaurant"
},
options: {
draftAndPublish: true
},
pluginOptions: {},
attributes: {
name: { /*...*/ },
description: { /*...*/ },
createdAt: { /*...*/ },
updatedAt: { /*...*/ },
publishedAt: { /*...*/ },
createdBy: { /*...*/ },
updatedBy: { /*...*/ },
locale: { /*...*/ },
},
apiName: "restaurant",
globalId: "Restaurants",
uid: "api::restaurant.restaurant",
modelType: "contentType",
modelName: "restaurant",
actions: { /*...*/ },
lifecycles: { /*...*/ },
},
action: "findOne",
params: {
documentId: 'hp7hjvrbt8rcgkmabntu0aoq',
locale: undefined,
status: "publish"
populate: { /*...*/ },
}
}
{
uid: "api::restaurant.restaurant",
contentType: {
kind: "collectionType",
collectionName: "restaurants",
info: {
singularName: "restaurant",
pluralName: "restaurants",
displayName: "restaurant"
},
options: {
draftAndPublish: true
},
pluginOptions: {},
attributes: {
name: { /*...*/ },
description: { /*...*/ },
createdAt: { /*...*/ },
updatedAt: { /*...*/ },
publishedAt: { /*...*/ },
createdBy: { /*...*/ },
updatedBy: { /*...*/ },
locale: { /*...*/ },
},
apiName: "restaurant",
globalId: "Restaurants",
uid: "api::restaurant.restaurant",
modelType: "contentType",
modelName: "restaurant",
actions: { /*...*/ },
lifecycles: { /*...*/ },
},
action: "findMany",
params: {
filters: { /*...*/ },
status: "draft",
locale: null,
fields: ['name', 'description'],
}
}
{
uid: "api::restaurant.restaurant",
contentType: {
kind: "collectionType",
collectionName: "restaurants",
info: {
singularName: "restaurant",
pluralName: "restaurants",
displayName: "restaurant"
},
options: {
draftAndPublish: true
},
pluginOptions: {},
attributes: {
name: { /*...*/ },
description: { /*...*/ },
createdAt: { /*...*/ },
updatedAt: { /*...*/ },
publishedAt: { /*...*/ },
createdBy: { /*...*/ },
updatedBy: { /*...*/ },
locale: { /*...*/ },
},
apiName: "restaurant",
globalId: "Restaurants",
uid: "api::restaurant.restaurant",
modelType: "contentType",
modelName: "restaurant",
actions: { /*...*/ },
lifecycles: { /*...*/ },
},
action: "create",
params: {
data: { /*...*/ },
status: "draft",
populate: { /*...*/ },
}
}
{
uid: "api::restaurant.restaurant",
contentType: {
kind: "collectionType",
collectionName: "restaurants",
info: {
singularName: "restaurant",
pluralName: "restaurants",
displayName: "restaurant"
},
options: {
draftAndPublish: true
},
pluginOptions: {},
attributes: {
name: { /*...*/ },
description: { /*...*/ },
createdAt: { /*...*/ },
updatedAt: { /*...*/ },
publishedAt: { /*...*/ },
createdBy: { /*...*/ },
updatedBy: { /*...*/ },
locale: { /*...*/ },
},
apiName: "restaurant",
globalId: "Restaurants",
uid: "api::restaurant.restaurant",
modelType: "contentType",
modelName: "restaurant",
actions: { /*...*/ },
lifecycles: { /*...*/ },
},
action: "update",
params: {
data: { /*...*/ },
documentId: 'hp7hjvrbt8rcgkmabntu0aoq',
locale: undefined,
status: "draft"
populate: { /*...*/ },
}
}
{
uid: "api::restaurant.restaurant",
contentType: {
kind: "collectionType",
collectionName: "restaurants",
info: {
singularName: "restaurant",
pluralName: "restaurants",
displayName: "restaurant"
},
options: {
draftAndPublish: true
},
pluginOptions: {},
attributes: {
name: { /*...*/ },
description: { /*...*/ },
createdAt: { /*...*/ },
updatedAt: { /*...*/ },
publishedAt: { /*...*/ },
createdBy: { /*...*/ },
updatedBy: { /*...*/ },
locale: { /*...*/ },
},
apiName: "restaurant",
globalId: "Restaurants",
uid: "api::restaurant.restaurant",
modelType: "contentType",
modelName: "restaurant",
actions: { /*...*/ },
lifecycles: { /*...*/ },
},
action: "delete",
params: {
data: { /*...*/ },
documentId: 'hp7hjvrbt8rcgkmabntu0aoq',
locale: "*",
populate: { /*...*/ },
}
}
next
next 是一个没有参数的函数,它调用堆栈中的下一个中间件并返回其响应。
示例
strapi.documents.use((context, next) => {
return next();
});
在哪里注册
🌐 Where to register
一般来说,你应该在 Strapi 注册阶段注册你的中间件。
🌐 Generaly speaking you should register your middlewares during the Strapi registration phase.
用户
🌐 Users
中间件必须在通用的 register() 生命周期方法中注册:
🌐 The middleware must be registered in the general register() lifecycle method:
module.exports = {
register({ strapi }) {
strapi.documents.use((context, next) => {
// your logic
return next();
});
},
// bootstrap({ strapi }) {},
// destroy({ strapi }) {},
};
插件开发者
🌐 Plugin developers
中间件必须在插件的 register() 生命周期方法中注册:
🌐 The middleware must be registered in the plugin's register() lifecycle method:
module.exports = {
register({ strapi }) {
strapi.documents.use((context, next) => {
// your logic
return next();
});
},
// bootstrap({ strapi }) {},
// destroy({ strapi }) {},
};
实现中间件
🌐 Implementing a middleware
在实现中间件时,总是要返回来自 next() 的响应。
如果不这样做,将会导致 Strapi 应用出错。
🌐 When implementing a middleware, always return the response from next().
Failing to do this will break the Strapi application.
例子
🌐 Examples
const applyTo = ['api::article.article'];
strapi.documents.use((context, next) => {
// Only run for certain content types
if (!applyTo.includes(context.uid)) {
return next();
}
// Only run for certain actions
if (['create', 'update'].includes(context.action)) {
context.params.data.fullName = `${context.params.data.firstName} ${context.params.data.lastName}`;
}
const result = await next();
// do something with the result before returning it
return result
});
文档服务 API 会根据调用的方法触发各种数据库生命周期钩子。完整参考请参见 文档服务 API:生命周期钩子。
🌐 The Document Service API triggers various database lifecycle hooks based on which method is called. For a complete reference, see Document Service API: Lifecycle hooks.