无法通过具有 FastifyAdapter 的应用程序的 NestJS 中间件获取请求正文

问题描述 投票:0回答:1

我正在处理 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()
javascript node.js typescript nestjs nestjs-fastify
1个回答
0
投票

Fastify 和 Express 对待中间件的方式不同

当将 Fastify 与 NestJS 结合使用时,Fastify 使用名为

middie
的包来支持 Express 等中间件,但这种兼容性并没有完全扩展到像
req.body
这样的东西(顺便说一句 - 同样适用于
req.params
req.query
)中间件的方式与 Express 相同。

核心问题

在 NestJS 中使用 Fastify 时,这些属性不会自动填充到中间件中,因为 Fastify 在执行中间件后处理路由参数和查询参数。这就是为什么您在中间件中看到

req.body
未定义。

要解决此问题,您可以根据您想要实现的目标采取多种方法。

解决方案:使用 Interceptors 或 Guards 来代替,它们在路由匹配后可以访问这些属性

示例:使用拦截器 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();
  }
}

参考

  1. https://fastify.dev/docs/latest/Reference/Middleware/
  2. https://github.com/fastify/middie
  3. https://docs.nestjs.com/interceptors
© www.soinside.com 2019 - 2024. All rights reserved.