Nest自定义中间件的使用
实现一个自定义中间件类
1 2 3 4 5 6 7 8 9
| import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable() export class Logger implements NestMiddleware { use(req: any, res: any, next: () => void) { console.log('loggerMiddleWare-调用'); next(); } }
|
自定义中间件实现了NestMiddleware类,只有一个方法use
1 2 3 4 5 6 7 8
|
export interface NestMiddleware<TRequest = any, TResponse = any> { use(req: TRequest, res: TResponse, next: (error?: Error | any) => void): any; }
|
在中间件中能够获取到请求信息,能够通过next方法执行下一个中间件,
也能够提前响应请求
1 2 3 4 5 6 7 8
| import { Injectable, NestMiddleware } from '@nestjs/common'; import { Request, Response, NextFunction } from 'express'; @Injectable() export class Logger implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { res.send({ message: '中间件拦截结束响应' }); } }
|
中间件中注入其他服务
Nest将中间件做成类的另一个好处就是可以注入其他服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Injectable() export class Logger implements NestMiddleware {
constructor(private readonly appService: AppService) {}
use(req: Request, res: Response, next: NextFunction) { console.log('中间件拦截'); console.log('中间件调用其他服务:', this.appService.getHello()); next(); } }
|
自定义中间件的使用
在module中使用,module实现NestModule类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| import { Module, NestModule, MiddlewareConsumer, RequestMethod, } from '@nestjs/common'; import { Logger } from './middleWare/logger.middleware';
export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer.apply(Logger).forRoutes({ path: '*', method: RequestMethod.GET }); } }
|
- 实现的
NestModule中的configure方法
configure 方法接受一个参数 consumer (消费者)
configure 通过apply方法接受一个或多个中间件,返回一个MiddlewareConfigProxy 中间件代理
- 代理对象上有
exclude: 排除的路由, forRoutes: 要匹配的路由 两个方法
forRoutes的匹配方式
1 2 3 4 5 6 7 8 9
|
consumer.apply(Logger).forRoutes('*');
consumer.apply(Logger).forRoutes({ path: '*', method: RequestMethod.GET });
consumer.apply(Logger).forRoutes(appController);
|
函数式中间件
1 2 3 4 5 6 7
| import { Request, Response, NextFunction } from 'express';
export function LoggerFn(req: Request, res: Response, next: NextFunction) { console.log('函数式中间件拦截'); next(); }
|
结构跟自定义类中间件一样, nest全局中间件只能使用函数式的中间件.