Strapi的官方文档提供了扩展插件的方式,例如在src/extensions/users-permissions/strapi-server.ts
中自定义,但文档提供的例子直接重写了原有插件的函数,而无法通过类似自定义API调用super.find()
等方式调用原有插件的函数。
// 自定义API的方式
const uid: Common.UID.ContentType = 'api::api-name···';
export default factories.createCoreController(uid, ({
strapi: Strapi }) => ({
async find(ctx: Context) {
// TODO ...
return await super.find(ctx);
},
}));
此时需要将原插件的函数复制出来,并在重写的函数里调用,以自定义/users/me接口为例。
users-permissions的/users/me接口提供了对获得当前用户信息的方法,若需要自定义获得哪些信息,可通过修改原有me函数实现,users-permissions对me函数的定义位于@strapi/plugin-users-permissions/server/controllers/user.js
中,尝试通过导入这个函数,并在自定义的me函数中调用这个函数。
失败的方案
进一步观察代码,该me函数位于user.js的导出对象中,user.js的导出对象是controllers导出对象的成员,位于@strapi/plugin-users-permissions/server/controllers/index.js
中,controllers又是server导出函数的返回值成员,位于@strapi/plugin-users-permissions/server/index.js
中,故要访问user.js中的方法,可通过以下方式。
const {
controllers } = server();
controllers.user.me(ctx);
导入原有me函数时,要注意users-permissions插件的导出对象名,查看/@strapi/plugin-users-permissions/package.json
发现,其exports
对象导出名为strapi-server
,故实际引用users-permissions的server对象,需要使用
import server from '@strapi/plugin-users-permissions/strapi-server';
此时,如果在重写的me函数中直接调用controllers.user.me(ctx);
则会陷入死递归,因为Strapi初始化时已经将原有的me函数覆盖为自定义的me函数,实际上调用controllers.user.me(ctx);
即调用的当前函数,故该方法无法实现。
可行的方案
既然如此,就把整个原有的me函数照搬过来,相当于复制了一份me函数,进入@strapi/plugin-users-permissions/server/controllers/user.js
中,发现me函数的定义如下:
/**
* Retrieve authenticated user.
* @return {Object|Array}
*/
async me(ctx) {
const authUser = ctx.state.user;
const {
query } = ctx;
if (!authUser) {
return ctx.unauthorized();
}
await validateQuery(query, ctx);
const sanitizedQuery = await