我正在处理 NestJS 项目,并且想要记录每个请求。我在 REST API 中使用 Fastify。我制作了一个嵌套中间件来获取请求正文:
import { HttpException, Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
const { httpVersion, headers, method, baseUrl, params, query, body } = req;
// body is Undefined!
console.log('Request Body...', body);
next();
}
}
当我将日志打印到控制台时,我得到了输出未定义。
app.module.ts:
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes('*');
}
}
main.ts:
import { NestFactory } from '@nestjs/core';
import {
FastifyAdapter,
NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter()
);
await app.listen(3000);
}
bootstrap()
当将 Fastify 与 NestJS 结合使用时,Fastify 使用名为
middie
的包来支持 Express 等中间件,但这种兼容性并没有完全扩展到像 req.body
这样的东西(顺便说一句 - 同样适用于 req.params
和 req.query
)中间件的方式与 Express 相同。
在 NestJS 中使用 Fastify 时,这些属性不会自动填充到中间件中,因为 Fastify 在执行中间件后处理路由参数和查询参数。这就是为什么您在中间件中看到
req.body
未定义。
要解决此问题,您可以根据您想要实现的目标采取多种方法。
示例:使用拦截器 NestJS 中的拦截器在路由过程之后应用,因此 req.params、req.query 和 req.body 是可以访问的。
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { FastifyRequest } from 'fastify';
@Injectable()
export class ParamLoggingInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
const request = context.switchToHttp().getRequest<FastifyRequest>();
// Now you can access request parameters, query, and body
console.log('Request Params:', request.params);
console.log('Query Params:', request.query);
console.log('Body:', request.body);
return next.handle();
}
}
参考