欢迎继续关注NestJs学习之旅系列文章中间件中间件是在routinghandler之前调用的一个函数。中间件功能可以访问请求和响应对象。用过koa和express的朋友应该都知道,中间件是一个很核心的功能,尤其是koa,核心就是中间件,连路由功能都是由中间件提供的。中间件可以提供以下功能:在运行过程中执行任意代码,对请求和响应进行更改结束本次请求的响应继续调用下一个中间件示例NestJs使用@Injectable()装饰中间件,被装饰的对象需要实现NestMiddleware接口.下面是日志中间件的实现://log.middleware.tsimport{Injectable,NestMiddleware}from'@nestjs/common';import{Request,Response}from'express';@Injectable()exportclassLogMiddlewareimplementsNestMiddleware{use(req:Request,resp:Response,next:Function){console.log(`${req.method}${req.path}`)next();}}//app.module.tsimport{Module,NestModule,MiddlewareConsumer}from'@nestjs/common';import{LogMiddleware}from'./common/middleware/log.middleware';import{UserModule}from'./user/user.module';@Module({imports:[UserModule],})exportclassAppModuleimplementsNestModule{configure(consumer:MiddlewareConsumer){consumer.apply(LogMiddleware).forRoutes('users');}}将中间件应用到请求方法Users路由应用中间件。如果只需要对特定的请求方式应用中间件,比如GET请求,可以使用如下方法:import{Module,NestModule,MiddlewareConsumer}from'@nestjs/common';从'./common/middleware/log.middleware'导入{LogMiddleware};从中导入{UserModule}'./user/user.module';@Module({imports:[UserModule],})exportclassAppModuleimplementsNestModule{configure(consumer:MiddlewareConsumer){consumer.apply(LogMiddleware).forRoutes({path:'users',方法:RequestMethod.GET});}}应用多个中间件import{Module,NestModule,MiddlewareConsumer}from'@nestjs/common';import{LogMiddleware}from'./common/middleware/log.middleware';import{UserModule}from'./user/user.module';@Module({imports:[UserModule],})exportclassAppModuleimplementsNestModule{configure(consumer:MiddlewareConsumer){consumer.apply(LogMiddleware,OtherMiddleware).forRoutes({path:'users',method:RequestMethod.得到});}}根据控制器名称申请中间件以上代码都是针对固定的路由地址申请中间件。在NestJs中,路由地址是由装饰器定义的。如果controller的路由地址变了,但是这里的中间件没有变,就会出现问题NestJs在使用中间件时提供了基于控制器的注册方式:import{Module,NestModule,MiddlewareConsumer}from'@nestjs/common';从'./common/middleware/log.middleware'导入{LogMiddleware};import{UserModule}from'./user/user.module';@Module({imports:[UserModule],})exportclassAppModuleimplementsNestModule{configure(consumer:MiddlewareConsumer){consumer.apply(LogMiddleware).forRoutes(UserController);}}Excludespecifiedroutes在某些场景下,将中间件应用到controller后,需要绕过几个方法。比如登录验证中间件应该允许登录路由,否则任何人都无法登录成功。从'@nestjs/common'导入{Module,NestModule,MiddlewareConsumer};从'./common/middleware/log.middleware'导入{LogMiddleware};从'./user/user.module'导入{UserModule};@Module({imports:[UserModule],})exportclassAppModuleimplementsNestModule{configure(consumer:MiddlewareConsumer){consumer.apply(LogMiddleware).exclude({path:'users/login',method:RequestMethod.GET}).forRoutes(用户控制器);}}全局中间件类似于全局模块,中间件也可以全局注册,对每条路由生效。//main.tsconstapp=awaitNestFactory.create(AppModule);app.use(LogMiddleware);awaitapp.listen(3000);结束中间件赋予了框架极大的灵活性,可以根据功能抽象成中间件,达到“可插拔”的目的。如果觉得自己有所收获,请分享给更多有需要的朋友,谢谢!如果你想交流更多关于NestJs的知识,欢迎加入群讨论!
