如何在NestJS中正确配置morgan-body作为请求响应日志中间件
问题原因&修复方案
错误原因解析
- 第一个报错「Void function return value is used」:
morganBody本身不是可传入app.use()的标准Express中间件函数,它的执行逻辑是直接向传入的应用实例挂载日志拦截逻辑,本身没有返回值,将其调用结果传入app.use()就会触发该错误。 - 第二个TS报错「TS2345: Argument of type 'INestApplication' is not assignable to parameter of type 'Application'」:Nest的
INestApplication是上层封装的抽象实例,不是morganBody要求的原生Express Application实例,需要先获取底层的HTTP服务实例再传入。
正确配置方案
基础配置(直接写在main.ts中)
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import bodyParser from 'body-parser'; import morganBody from 'morgan-body'; import { Logger } from '@nestjs/common'; async function bootstrap() { const app = await NestFactory.create(AppModule); // 先配置body解析中间件,必须放在morganBody调用之前 app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); // 获取底层原生Express实例 const expressApp = app.getHttpAdapter().getInstance(); const logger = new Logger('Request'); // 直接调用morganBody挂载日志逻辑,无需传入app.use morganBody(expressApp, { // 自定义日志输出到Nest内置Logger stream: { write: (message) => logger.log(message.replace('\n', '')), }, // 其他自定义配置项示例 // logRequestBody: true, // logResponseBody: true, }); // 后续其他配置、路由注册逻辑 await app.listen(3000); } bootstrap();
封装为独立函数的写法
// request-logging.ts import { INestApplication } from '@nestjs/common'; import morganBody from 'morgan-body'; import { Logger } from '@nestjs/common'; import bodyParser from 'body-parser'; export function useRequestLogging(app: INestApplication) { app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); const expressApp = app.getHttpAdapter().getInstance(); const logger = new Logger('Request'); morganBody(expressApp, { stream: { write: (message) => logger.log(message.replace('\n', '')), }, }); }
调用方式保持原有写法即可:
// main.ts async function bootstrap() { const app = await NestFactory.create(AppModule); useRequestLogging(app); // 其他配置逻辑 await app.listen(3000); }
注意事项
- 必须在
morganBody调用前完成body解析中间件的配置,否则无法捕获请求体内容 morganBody的调用需要放在所有业务路由、接口注册之前,才能拦截到全部请求- 该配置仅适用于Nest使用Express作为HTTP适配器的场景(Nest默认使用Express),如果使用Fastify适配器需要更换为对应Fastify生态的日志工具
内容的提问来源于stack exchange,提问作者Sergino
相关产品推荐
相关产品推荐

