[Nest.js] Intercepter

Woong·2022년 12월 15일
0

Nestjs

목록 보기
13/28

개요

  • @Injectable 데코레이터가 있는 클래스
    • NestIntercepter 인터페이스를 구현
  • 로직 수행 전/후 바인딩
  • 응답 혹은 exception 변환
  • 기본 함수 동작을 확장
  • 특정 조건에 따른 함수 재정의 (ex.캐싱 등)
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`)),
      );
  }
}

적용하기

*@UseIntercepters 을 통해 적용

  • global, controller, method 범위로 적용 가능
@UseInterceptors(LoggingInterceptor)
export class CatsController {}
  • Module 에서 직접 적용
import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_INTERCEPTOR,
      useClass: LoggingInterceptor,
    },
  ],
})
export class AppModule {}

응답 변경하기

  • ex) rxjs 의 map 을 통해 응답을 변경
@Injectable()
export class LoggingInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    console.log('Before...');

    const now = Date.now();
    return next
      .handle()
      .pipe(
        map((data) => ({
          success: 'true',
          data
      }));
  }
}

exception 재정의하기

  • rxjs 의 catchError 를 통해 exception 을 재정의
import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  BadGatewayException,
  CallHandler,
} from '@nestjs/common';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable()
export class ErrorsInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next
      .handle()
      .pipe(
        catchError(err => throwError(() => new BadGatewayException())),
      );
  }
}

timeout 적용하기

  • ex) rxjs 의 timeout 을 이용해 5초 timeout 적용
import { Injectable, NestInterceptor, ExecutionContext, CallHandler, RequestTimeoutException } from '@nestjs/common';
import { Observable, throwError, TimeoutError } from 'rxjs';
import { catchError, timeout } from 'rxjs/operators';

@Injectable()
export class TimeoutInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      timeout(5000),
      catchError(err => {
        if (err instanceof TimeoutError) {
          return throwError(() => new RequestTimeoutException());
        }
        return throwError(() => err);
      }),
    );
  };
};

reference

0개의 댓글