NestJS - Interceptor

Server_side·2024년 3월 2일
1
post-custom-banner

Interceptor

Interceptor(인터셉터)란 무엇일까?
공식문서를 통해 확인해 보면 NestInterceptor 인터페이스를 구현하는 @Injectable() 데코레이터가 달린 클래스를 말한다.

Interceptor는 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)에서 영감을 받아 만든 다양한 기능을 가진 집합이라고 정의하며 interceptor로 가능한 작업은 다음과 같다고 설명한다. (AOP에 대해서는 따로 포스팅하도록 하겠다)

  • 메서드 실행 전/후 추가 로직 수행
  • 함수로부터 반환된 결과/예외 변환
  • 기본 함수 거동(동작) 확장
  • 특정 조건에 따른 함수의 완전한 오버라이드(재정의) (예시: 캐싱 목적)

Interceptor를 직역해보자면 '가로챔' 즉, 중간에서 가로채서 무언가를 해준다고 직감적으로 알 수 있다.
간단하게 위에서 말한 것과 같이 요청/응답을 가로채서 무언가 추가적인 가공을 해준다고 생각하면 좋을 것 같다.


Interceptor 적용법

Interceptor를 적용하기 위해선 @UseInterceptors() 데코레이터로 적용하며, Pipe/Guard와 동일하게 Global/Controller/Method에 적용 가능하다.

예시:
다음 코드는 어떤 요청/응답에 소요되는 시간을 측정하기 위해 작성된 Interceptor다.
return 전에는 메서드에 실행(도달) 전 Interceptor에서 실행될 로직을 작성하며, return에는 메서드 실행 이 후 실행될 로직을 작성하면 된다.

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

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

    const now = Date.now();
    return next
      .handle()
      .pipe(
        tap(() => console.log(`After... ${Date.now() - now}ms`)),
      );
  }
}

해당 Interceptor를 전역으로 적용하기 위해선 main.ts에 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();

이외에도 응답을 하나의 양식으로 만들어 클라이언트로 동일한 양식을 가진 응답이 전송될 수 있도록 만들 수도 있다.
즉, 어떻게 응용하느냐에 따라 사용 방법은 무궁무진해질 수 있다는 것이다.


참고문헌

NestJS 공식 문서 - Interceptor

profile
아마도 난 백엔드 style?
post-custom-banner

0개의 댓글