Nest自定义中间件MiddleWare

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
/**
* @see [Middleware](https://docs.nestjs.com/middleware)
*
* @publicApi
*/
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 {
// @Inject(AppService)
// private readonly appService: AppService;

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
// 以下三种方式均可传多个参数匹配多个
// 方式一: route匹配
consumer.apply(Logger).forRoutes('*');

// 方式二:routeInfo匹配
consumer.apply(Logger).forRoutes({ path: '*', method: RequestMethod.GET });

// 方式三:控制器匹配
consumer.apply(Logger).forRoutes(appController);

函数式中间件

1
2
3
4
5
6
7
// loggerFn.middleware.ts
import { Request, Response, NextFunction } from 'express';

export function LoggerFn(req: Request, res: Response, next: NextFunction) {
console.log('函数式中间件拦截');
next();
}

结构跟自定义类中间件一样, nest全局中间件只能使用函数式的中间件.


Nest自定义中间件MiddleWare
https://avatar0813.github.io/2023/06/11/nest/Nest自定义中间件/
作者
avatar
发布于
2023年6月11日
许可协议