[Nest.js] middleware

Woong·2022년 11월 23일
0

Nestjs

목록 보기
4/28

개요

  • middleware 는 라우트 핸들러가 호출되기 전에 호출됨
  • 요청, 응답 내용 변경 가능
  • NestMiddleware 인터페이스 상속, @Injectable 데코레이터 선언
    • nest g middleware <name> 으로 생성시 자동 완성되어 생성됨
  • 응답은 res.on('finish', () => {..} 으로 응답을 확인할 수 있다.
  • ex)
import { Injectable, NestMiddleware } from '@nestjs/common';
import { Request, Response, NextFunction } from 'express';

@Injectable()
export class LoggerMiddleware implements NestMiddleware {
  use(req: Request, res: Response, next: NextFunction) {
    console.log(req.ip);
    console.log(req.originUrl);
    res.on('finish', () => {
      console.log(res.statusCode);
    });
    next();
  }
}
  • ex) header 확인하고자 한다면
use(req: Request, res: Response, next: NextFunction) {
  // ex) header 에서 secret 정보를 보려 한다면
  let secret = req.headers['secret']
  ...
}

middleware 적용하기

  • Module 의 configure 메소드를 통해 injection

    • @Module 데코레이터에서 선언하는 것이 아니니 주의

    • apply 메소드에 미들웨어 정의

      • 한번에 여러 미들웨어 적용하는 것도 가능
    • forRoutes 메소드에 라우트 핸들러 정의

      • ex) /cats 라우트 핸들러에 대해, 컨트롤러 도달 전 미들웨어 호출하도록 인젝션

        import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
        import { LoggerMiddleware } from './common/middleware/logger.middleware';
        import { CatsModule } from './cats/cats.module';
        
        @Module({
          imports: [CatsModule],
        })
        export class AppModule implements NestModule {
          configure(consumer: MiddlewareConsumer) {
            consumer
              .apply(LoggerMiddleware)
              .forRoutes('cats');
          }
        }
    • forRoutes 메소드에 특정 method에 대해서만 적용하는 것도 가능

      • ex) /catsGET 요청에 대해서 적용

        import { Module, NestModule, RequestMethod, MiddlewareConsumer } from '@nestjs/common';
        import { LoggerMiddleware } from './common/middleware/logger.middleware';
        import { CatsModule } from './cats/cats.module';
        
        @Module({
          imports: [CatsModule],
        })
        export class AppModule implements NestModule {
          configure(consumer: MiddlewareConsumer) {
            consumer
              .apply(LoggerMiddleware)
              .forRoutes({ path: 'cats', method: RequestMethod.GET });
          }
        }
    • 제외는 exclude 를 통해 적용

    consumer
    .apply(LoggerMiddleware)
    .exclude(
      { path: 'cats', method: RequestMethod.GET },
      { path: 'cats', method: RequestMethod.POST },
      'cats/(.*)',
    )
    .forRoutes(CatsController);
  • MiddleWareConsumer 는 helper 클래스

    • 미들웨어를 관리하기 위한 여러 built-in 메소드 포함

Functional middleware

  • class 가 아닌 function 형태의 미들웨어를 사용할 수도 있다.
import { Request, Response, NextFunction } from 'express';

export function logger(req: Request, res: Response, next: NextFunction) {
  console.log(`Request...`);
  next();
};
  • module 적용에서도 function 이름으로 적용
consumer
  .apply(logger)
  .forRoutes(CatsController);

Global middleware

  • app.use 를 통해 전역으로 미들웨어 적용 가능
//main.ts

const app = await NestFactory.create(AppModule);
app.use(logger);
await app.listen(3000);

reference

0개의 댓글