NestJS / / 2024. 11. 25. 03:25

NestJS Interceptor

  • NestJS 인터셉터(Interceptor)*는 요청(Request)과 응답(Response)을 가로채서 전처리 및 후처리를 수행할 수 있는 기능을 제공합니다. 인터셉터는 NestJS의 핵심 기능 중 하나로, 주로 다음과 같은 목적에 사용됩니다:
  1. 공통 작업 처리: 요청 또는 응답에 대해 반복적으로 실행해야 하는 작업을 중앙에서 처리.
  2. 응답 변환: 컨트롤러에서 반환된 데이터를 수정하거나 포맷팅.
  3. 로그ging 및 모니터링: 요청/응답 시간 측정 및 디버깅 정보 로깅.
  4. 캐싱: 이미 처리된 결과를 재사용하기 위해 응답 데이터를 캐시.

인터셉터의 동작 방식

인터셉터는 요청과 응답 사이의 흐름을 가로채서 다음과 같은 두 가지 단계에서 작업을 수행할 수 있습니다:

  • 전처리(Pre-processing): 요청이 컨트롤러로 전달되기 전에 실행.
  • 후처리(Post-processing): 컨트롤러 또는 서비스에서 반환된 응답을 클라이언트로 보내기 전에 실행.

인터셉터 구현

NestJS에서 인터셉터는 @Injectable() 데코레이터를 사용하여 클래스 형태로 정의됩니다. 인터셉터는 NestInterceptor 인터페이스를 구현해야 하며, intercept 메서드를 포함합니다.

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before handling request');

    const now = Date.now();
    return next.handle().pipe(
      map((data) => {
        console.log(`After handling request: ${Date.now() - now}ms`);
        return data;// 응답 데이터를 그대로 반환하거나 변환 가능
      }),
    );
  }
}

intercept 메서드 매개변수

  • ExecutionContext: 현재 실행 컨텍스트를 나타내며, 요청, 컨트롤러 및 핸들러와 관련된 정보를 포함.
  • CallHandler: 다음 미들웨어 또는 핸들러로 요청을 전달하고, 응답 스트림을 처리할 수 있는 메서드를 제공.

인터셉터 적용 방법

  1. 글로벌 범위로 적용

    • app.useGlobalInterceptors() 메서드를 사용하여 앱 전체에 적용.

      import { NestFactory } from '@nestjs/core';
      import { AppModule } from './app.module';
      import { LoggingInterceptor } from './logging.interceptor';
      
      async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      app.useGlobalInterceptors(new LoggingInterceptor());
      await app.listen(3000);
      }
      bootstrap();
  2. 컨트롤러 단위로 적용

    • @UseInterceptors() 데코레이터를 사용하여 특정 컨트롤러 또는 핸들러에 적용.

      import { Controller, Get, UseInterceptors } from '@nestjs/common';
      import { LoggingInterceptor } from './logging.interceptor';
      
      @Controller('example')
      @UseInterceptors(LoggingInterceptor)
      export class ExampleController {
      @Get()
      getExample() {
        return { message: 'This is an example response' };
      }
      }
  3. 핸들러 단위로 적용

    • 특정 메서드에만 적용 가능.

      @Controller('example')
      export class ExampleController {
      @Get()
      @UseInterceptors(LoggingInterceptor)
      getExample() {
        return { message: 'This is an example response' };
      }
      }

인터셉터와 RxJS

인터셉터는 CallHandler를 통해 RxJS의 Observable 스트림을 반환합니다. 이를 활용하여 map, catchError 등 RxJS 연산자를 사용해 응답 데이터를 변환하거나 에러를 처리할 수 있습니다.

예를 들어:

import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class TransformInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map(data => ({ status: 'success', data })),// 응답 데이터를 새로운 형식으로 변환
    );
  }
}

활용 예시

  1. 응답 데이터 포맷팅
    • 모든 응답 데이터를 특정 형식으로 반환.
  2. 로그ging
    • 요청 처리 시간 및 관련 메타데이터 기록.
  3. 권한 검사
    • 요청 데이터를 기반으로 특정 작업 수행 전 사용자 권한을 확인.
  4. 캐싱
    • 이전 응답 결과를 캐싱하여 성능 최적화.

'NestJS' 카테고리의 다른 글

Class Validator 정리  (1) 2024.12.23
NestJS Pagination Common  (0) 2024.11.20
NestJS 페이징처리  (0) 2024.11.19
NestJS Class-transfomer  (0) 2024.11.18
NestJS DTO,Validation  (0) 2024.11.18
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유