根据文档去学习使用Web中间件
什么是Web中间件
Web 中间件是在控制器调用 之前 和 之后(部分) 调用的函数。 中间件函数可以访问请求和响应对象。
不同的上层 Web 框架中间件形式不同,EggJS 的中间件形式和 Koa 的中间件形式相同,都是基于洋葱圈模型。而 Express 则是传统的队列模型。
Web中间件的作用
对于Midway定义的Web中间件和我使用koa时候的拦截有些类似,可以非常方便的实现后置处理逻辑。
举例说明:
在koa中使用全局拦截判断请求头携带的token是否正确
app.use(async (ctx, next) => {
let url = ctx.request.url
list.forEach((item,index)=>{if(item.name === url){ key=index }})
if(!~key){
list.push({name:ctx.request.url,count:1});
if( url === '/login'){
await next()
}else{
let token = ctx.request.header.token||[]
let user = await tools.search(User,{token},"all")
if(user.length){
await next()
}else{
ctx.body = {
"retCode": false,
"resultMsg": '登录已失效请重新登录',
"errorCode": 3
}
}
}
}else{
if( url === '/login'){
await next()
}else{
let token = ctx.request.header.token||[]
let user = await tools.search(User,{token},"all")
if(user.length){
await next()
}else{
ctx.body = {
"retCode": false,
"resultMsg": '登录已失效请重新登录',
"errorCode": 3
}
}
}
}
})
Midway的Web中间件用官方例子说明
export class TokenMiddleware implements IWebMiddleware {
resolve() {
return async (ctx: Context, next: IMidwayWebNext) => {
// 控制器前执行的逻辑
const startTime = Date.now();
ctx.body = { name:false }
// 执行下一个 Web 中间件,最后执行到控制器
// await next();
// 控制器之后执行的逻辑
console.log(Date.now() - startTime);
};
}
}
如上所示await next() 控制是否执行控制器,光从使用上看就是Generator 函数的封装,yield 包含着控制器,这里逻辑判断可以直接使用koa的,但是后面的next不能再去执行了。
注:TokenMiddleware在使用时首字母小写驼峰命名具体原因如下
key属性说明
服务
使用服务的过程分为几部分:
-
1、使用
@Provide
装饰器暴露你的服务 -
2、在调用的代码处,使用
@Inject
装饰器注入你的服务 -
3、调用注入服务,执行对应的方法
Midway
的核心 “依赖注入” 容器会自动关联你的控制器(Controller
) 和服务(Service
),在运行过程中会自动初始化所有的代码,你无需手动初始化这些 Class
。
注入行为描述
Provide
装饰器的作用:
- 1、这个 Class,被依赖注入容器托管,会自动被实例化(new)
- 2、这个 Class,可以被其他在容器中的 Class 注入
而对应的 @Inject
装饰器,作用为:
- 1、在依赖注入容器中,找到对应的属性名,并赋值为对应的实例化对象
@Provide
和@Inject
装饰器是有参数的,并且他们是成对出现。
这个参数叫做 依赖注入标识符,这里先用 key 代替。
这里就涉及到了Midwayde默认行为了。
默认情况下:
-
1、
@Provide
取 类名的驼峰字符串 作为 key -
2、
@Inject
根据 规则 获取 key 规则如下: -
1、如果装饰器包含参数,则以 参数字符串 作为 key
-
2、如果没有参数,标注的 TS 类型为 Class,则将类
@Provide
的 key 作为 key -
3、如果没有参数,标注的 TS 类型为非 Class,则将 属性名 作为 key
两者相互一致即可关联。
export interface IService { }
// service
@Provide() // 这里暴露的 key 是userServiceexport
// 也可以自定义key @Provide('testService')但是@Inject中需要对应
class UserService implements IService {
//...
}
// controller
@Provide()
@Controller('/api/user')
export class APIController {
@Inject('userService')
// 对应@Provide @Inject('testService')
userService1: UserService;// 这里注入的 key 是 userService
@Inject()
userService2: UserService;
@Inject()
userService: IService;
}
总结
// middleware
export class TokenMiddleware implements IWebMiddleware {
resolve() {
return async (ctx: Context, next: IMidwayWebNext) => {
// 控制器前执行的逻辑
const startTime = Date.now();
ctx.body = { name:false }
// 执行下一个 Web 中间件,最后执行到控制器
// await next();
// 控制器之后执行的逻辑
console.log(Date.now() - startTime);
};
}
}
// 使用时
@Get('/', { middleware: [ 'tokenMiddleware' ]})
async home() {}