中间件(Middleware)
Uma 基于 Koa2,兼容 middleware。在已有中间件的基础上提供两种使用形式:插件形式、AOP 形式。
插件形式
使用
Uma
的插件机制很大部分是借用了 Koa
的中间件,通过插件来使用中间件更易于开发和维护,请尽量用插件形式来使用中间件,插件开发和使用请参阅 Plugin 参考文档
其它
为了方便插件使用已发布的中间件,插件配置(plugin.config.ts)可以配置中间件便捷使用,配置如下
// types
[middlewareName: string]: {
type: 'middleware', // 仅在使用中间件的时候配置 type
handler: Koa.Middleware,
}
1
2
3
4
5
2
3
4
5
// plugin.config.ts
// 基于 koa-views 配置模板中间件
import * as views from 'koa-views'
export default {
view: {
type: 'middleware',
handler: views('./views', {
map: { html: 'nunjucks' },
}),
},
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
请不要在插件配置( plugin.config.ts )中进行中间件的开发,让插件的配置更加纯粹。如需要请使用插件开发。Plugin 参考文档
如果要动态的加载中间件,请使用复合插件形式。Plugin 参考文档
AOP 装饰器形式
中间件和 Aspect.around 方式很相似,都是包裹异步方法。中间件是 next,around 是 proceed,但是他们有一些区别:
1、中间件不能处理参数,不能处理返回结果
2、切面可以对参数进行修改、判断、注入等操作,还可以对返回结果进行修改、校验、统一封装等操作
Uma 内置了将中间件转换为切面的方法 middlewareToAround
,因此我们可以以 AOP 的装饰器形式使用中间件,使用示例如下:
// app/src/controller/index.controller.ts AOP形式使用中间件
import * as path from 'path';
import { BaseController, Path, Aspect, Result } from '@umajs/core';
export default class Index extends BaseController {
@Aspect.around('mw')
@Path('/page')
page() {
console.log(this.userService.getDefaultUserAge());
return Result.view('index.html', { test: 3 })
}
}
// app/src/aspect/mw.aspect.ts 定义AOP
import { IAspect, middlewareToAround } from '@umajs/core';
const mwFn = function() { // 定义中间件
return async (ctx, next) => {
console.log("****** mw before ******");
await next();
console.log("****** mw after *******");
}
}
// 将中间件转换为切面方法
export default class implements IAspect {
// 第一种方法
// async around({ target, proceed, args }) {
// return await middlewareToAround(mwFn())({target, proceed, args});
// }
// 第二种方法
around = middlewareToAround(mwFn());
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
对于有局部加载需求的中间件,使用 AOP 形式代码结构更清晰,可读性更强,可以在controller
中直观的看到当前中间件的使用。