NestJS中间件是单例实例化还是每次请求实例化?
问题
我是NestJS新手,若有疏漏之处敬请谅解。当前我正在实现一个记录请求与响应的简易日志中间件,由于NestJS中中间件只能置于路由之前,因此我通过重写res.write和res.end方法,将响应数据块存入中间件内的chunks数组,实现代码如下:
export class Logger implements NestMiddleware { use(req: Request, res: Response, next: NextFunction) { const originalResWrite = res.write; const originalResEnd = res.end; const chunks = []; res.write = (...chunk) => { chunks.push(Buffer.from(chunk[0])); originalResWrite.apply(res, chunk); }; res.end = (...chunk) => { if (chunk[0]) { chunks.push(Buffer.from(chunk[0])); } const body = Buffer.concat(chunks).toString("utf8"); console.log({ requestBody: req.body, responseBody: JSON.parse(body) || body || {}, }); originalResEnd.apply(res, chunk); }; } }
但我担心若该中间件像Django中间件那样以单例模式实例化并被所有请求共享,chunks数组会混入多个请求的数据,导致日志混乱。我的中间件通过如下方式注册:
export class AppModule implements NestModule { configure(consumer: MiddlewareConsumer) { consumer .apply(Logger) .forRoutes('*'); } }
想咨询:在NestJS中,中间件是以单例模式实例化,还是每次请求到来时重新实例化?
回答
NestJS中的中间件默认是以单例模式实例化的,整个应用生命周期内只会创建一个中间件实例,所有请求都会复用这个实例。
但你完全不用担心chunks数组会混入多个请求的数据——因为chunks是在use方法内部声明的局部变量。每次有请求进入时,use方法都会被重新执行一次,此时会创建一个全新的chunks数组,这个数组的作用域仅限于当前请求的use方法执行上下文,和其他请求的chunks完全隔离。
只有当你在中间件类的实例级别定义属性(比如在类顶部声明private chunks: any[] = [])时,才会出现多个请求共享同一变量的问题。而你现在的写法是完全安全的,无需担心日志混乱。
内容的提问来源于stack exchange,提问作者Nullable Yogurt
相关产品推荐
相关产品推荐

