中间件
如何注册中间件?
中间件的注册方法一般写在 load 方法里
1export class MyPlugin extends Plugin {
2 load() {
3 this.app.acl.use();
4 this.app.resourcer.use();
5 this.app.use();
6 }
7}
说明:
app.acl.use()
添加资源权限级中间件,在权限判断之前执行
app.resourcer.use()
添加资源级中间件,只有请求已定义的 resource 时才执行
app.use()
添加应用级中间件,每次请求都执行
洋葱模型
1app.use(async (ctx, next) => {
2 ctx.body = ctx.body || [];
3 ctx.body.push(1);
4 await next();
5 ctx.body.push(2);
6});
7
8app.use(async (ctx, next) => {
9 ctx.body = ctx.body || [];
10 ctx.body.push(3);
11 await next();
12 ctx.body.push(4);
13});
访问 http://localhost:3000/api/hello 查看,浏览器响应的数据是:
内置中间件及执行顺序
bodyParser
cors
i18n
dataWrapping
db2resource
restApi
其实就是resourcer
auth
acl
acl.use()
添加的其他中间件
resourcer.use()
添加的其他中间件
action handler
app.use()
添加的其他中间件
也可以使用 before
或 after
将中间件插入到前面的某个 tag
标记的位置,如:
1app.use(m1, { tag: 'restApi' });
2app.resourcer.use(m2, { tag: 'parseToken' });
3app.resourcer.use(m3, { tag: 'checkRole' });
4// m4 将排在 m1 前面
5app.use(m4, { before: 'restApi' });
6// m5 会插入到 m2 和 m3 之间
7app.resourcer.use(m5, { after: 'parseToken', before: 'checkRole' });
如果未特殊指定位置,新增的中间件的执行顺序是:
- 优先执行 acl.use 添加的,
- 然后是 resourcer.use 添加的,包括 middleware handler 和 action handler,
- 最后是 app.use 添加的。
访问 http://localhost:3000/api/hello 查看,浏览器响应的数据是:
访问 http://localhost:3000/api/test:list 查看,浏览器响应的数据是:
1{"data": [5,3,7,1,2,8,4,6]}
resource 未定义,不执行 resourcer.use() 添加的中间件
1app.use(async (ctx, next) => {
2 ctx.body = ctx.body || [];
3 ctx.body.push(1);
4 await next();
5 ctx.body.push(2);
6});
7
8app.resourcer.use(async (ctx, next) => {
9 ctx.body = ctx.body || [];
10 ctx.body.push(3);
11 await next();
12 ctx.body.push(4);
13});
访问 http://localhost:3000/api/hello 查看,浏览器响应的数据是:
以上示例,hello 资源未定义,不会进入 resourcer,所以就不会执行 resourcer 里的中间件
辅助插件
开启开发工具,可以查看当前请求的中间件执行顺序和相关use的堆栈地址
