Sergino
Sergino

Reputation: 10838

how to setup morgan-boddy in nestjs

I want to setup morgan-boddy as a midldleware to log requests and responses.

So I've created a function like that:

export function RequestLogging(app) {
  const logger = new Logger('Request');
  app.use(
    morganBody(app, {
      stream: { // <--- error is here "Void function return value is used "
        write: (message) => logger.log(message.replace('\n', '')),
      },
    }),
  );
}

That I call on main.ts

// main.ts

async function bootstrap() {
    const app = await NestFactory.create(AppModule);
    useRequestLogging(app);
    // ...
}

However it seems does not work. I've got an error 'Void function return value is used' on line stream: {

Any idea how to fix?

UPDATE:

I tried to go different path and actually just stick morganBody in to main.ts as per docs:

  import bodyParser from 'body-parser';
  import morganBody from 'morgan-body';

  app.use(bodyParser.json());

  // hook morganBody to express app
  morganBody(app); <-- getting error here "TS2345: Argument of type 'INestApplication' is not assignable to parameter of type 'Application'."

I wish there was a proper documentation how to approach in nestjs.

Upvotes: 0

Views: 4430

Answers (1)

Jay McDoniel
Jay McDoniel

Reputation: 70600

This is a pretty interesting middleware. It ends up needing the express instance itself because it calls app.use(morgan) and app.response.send() under the hood. I would really look into some other solution instead of something that accesses the response in this way.

Either way: this set up works

import { Logger } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import * as morgan from 'morgan-body';

import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const logger = app.get(Logger);
  (morgan as any)(app.getHttpAdapter().getInstance(), {
    stream: {
      write: (message: string) => {
        logger.log(message.replace('\n', ''));
        return true;
      },
    },
  });
  await app.listen(3033);
}
bootstrap();

The types for the package are wrong as well, it's not a default export, but a named one, so import morgan from 'morgan-body' doesn't work as advertised (at least it didn't for me).

The return true is necessary because write expects a stream.writable() method, which has returns a boolean. You can just default this to true. Then you have to use app.getHttpAdapter().getInstance() so that you ensure you pass the express instance to the middleware. Again, wonky setup, but it works.

Upvotes: 1

Related Questions