express의 미들웨어와 동등함

NestMiddleware interface를 implements한 다음 미들웨어를 작성하면 됨

next()는 필수

import { Injectable, Logger, NestMiddleware } from '@nestjs/common';
import { NextFunction, Request, Response } from 'express';

// class가 아니더라도 funcitonal middleware로도 사용 가능
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  private logger = new Logger('HTTP');

  use(req: Request, res: Response, next: NextFunction): void {
    const { ip, method, originalUrl } = req;
    const userAgent = req.get('user-agent') || '';

    res.on('finish', () => {
      const { statusCode } = res;
      const contentLength = res.get('content-length');

      // console.log가 아니라 Logger.log or this.logger.log 사용함
      // 후자는 new Logger(context)에서 context를 넣어준 경우 사용
      // -> 이 로그가 어떤거랑 연관돼서 발생한 것인지 모르기 때문에 context로 구분하는거임
      this.logger.log(
        `${method} ${originalUrl} ${statusCode} ${contentLength} - ${userAgent} ${ip}`,
      );
    });

    next();
  }
}

app.module을 NestModule을 implements하고 사용

import { MiddlewareConsumer, Module, NestModule } from '@nestjs/common';
import { LoggerMiddleware } from './middlewares/logger.middleware';
import { AuthMiddleware } from './middlewares/auth.middleware';

export class AppModule implements NestModule {
  configure(consumer: MiddlewareConsumer) {
    // middleware는 consumer에 연결
    consumer.apply(LoggerMiddleware, AuthMiddleware).forRoutes('*');
  }
}

Global Middleware

app.module말고 main에서 app.use를 사용

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

  // global middleware
  app.use(JwtMiddleWare);

  await app.listen(PORT);
}

Excluding routes

특정 경로에서 미들웨어를 적용시키고 싶지 않은 경우

consumer
	.apply(LoggerMiddleware, AuthMiddleware)
	.exclude(
	  { path: 'cats', method: RequestMethod.POST }
	)
	.forRoutes('*');