[nest.js] interceptor사용법 적용예제 함께

interceptor란??
인터셉터에는 AOP( Aspect Oriented Programming ) 기술 에서 영감을 받은 일련의 유용한 기능이 있습니다 . 그들은 다음을 가능하게 합니다
- 메서드 실행 전/후에 추가 로직 바인딩
- 함수에서 반환된 결과 변환
- 함수에서 발생한 예외 변환
- 기본 기능 동작 확장
- 특정 조건에 따라 함수를 완전히 재정의합니다(예: 캐싱 목적).
결과적으로 최종 경로 처리기 실행 전후 에 사용자 지정 논리를 구현할 수 있습니다
AOP란??(관점 지향 프로그래밍:Aspect Oriented Programming)
기능별로 class를 분리했음에도 불구하고 생기는 중복코드의 단점을 해결하고자 나온 방식,
공통기능과 핵심부분을 분리하여,필요할 때에만 공통기능을 핵심부위에 넣어주는 방식

interceptor적용 예시
1)interceptor 파일 생성
//success. interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';
@Injectable()
export class successInterceptor 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`)));
}
}
2)controller 파일에 interceptor적용
//cats.controller.ts
@Controller('cats')
@UseInterceptors(successInterceptor)
@UseFilters(HttpExceptionFilter)
export class CatsController {
//dependency injection 의존성 주입
constructor(private readonly catsService: CatsService) {}
// cats/
@Get()
getAllcat() {
console.log('hello Controller');
return 'get all cat api';
}
http://localhost:8000/cats로 요청을 보내면 아래와 같은 결과가 나온다.

nest.js Request lifecycle에서 interceptors 부분
Before After
In general, the request lifecycle looks like the following:
- Incoming request
- Globally bound middleware
- Module bound middleware
- Global guards
- Controller guards
- Route guards
- Global interceptors (pre-controller)
- Controller interceptors (pre-controller)
- Route interceptors (pre-controller)
- Global pipes
- Controller pipes
- Route pipes
- Route parameter pipes
- Controller (method handler)
- Service (if exists)
- Route interceptor (post-request)
- Controller interceptor (post-request)
- Global interceptor (post-request)
- Exception filters (route, then controller, then global)
- Server response
위 과정을 통해 interceptor를 사용하여 controller가 작동되기 전 작동한 후 값들을 다룰수있다는 사실을 알게되었다.
interceptor을 이용하여 응답 값 다루기
interceptor 통해 성공하였을 경우에 즉, controller작동한 후 값을 다루어 보도록 하겠다.
// cats.controller.ts
@Get()//http://localhost:8000/
getAllcat() {
console.log('hello Controller');
return { cats: 'cats data' };// 이와 GET 요청을 받았을때 응답값 { cats: 'cats data' }을 준다고 만들어보았다.
}

이제 이 데이터값은 성공적으로 응답이 되었을때의 경우이니,
응답이 성공적일 경우 success:true를 추가하여 보내줄수있도록 interceptor를 변경해보겠다.
//success.interceptor.ts
import {
Injectable,
NestInterceptor,
ExecutionContext,
CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map, tap } from 'rxjs/operators';
@Injectable()
export class successInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
console.log('Before...');
return next.handle().pipe(map((data) => ({ success: true, data })));//변경된부분
}
}

다른 라우터에서도 동일 하게 적용된것을 확인 할 수있다.

위 과정을 통해 interceptor를 사용하여 controller가 작동되기 전 작동한 후 값들을 공통적으로 다룰수있다는 사실을 알게되었다.
레퍼런스
nest.js interceptor
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac
docs.nestjs.com
AOP 란??
관점지향 프로그래밍 AOP
AOP의 개요
hoi5088.medium.com
nest.js Request lifecycle
Documentation | NestJS - A progressive Node.js framework
Nest is a framework for building efficient, scalable Node.js server-side applications. It uses progressive JavaScript, is built with TypeScript and combines elements of OOP (Object Oriented Progamming), FP (Functional Programming), and FRP (Functional Reac
docs.nestjs.com