728x90
SMALL
Interceptors
인터셉터는 @Injectable() 데코레이터를 주석으로 다는 클래스이고, NestInterceptor 인터페이스를 implements한다.
인터셉터는 Aspect Oriented Programming(AOP, 관점 지향 프로그래밍) 기술에서 영감 받은 유용한 기능들을 가지고 있다.
- bind extra logic before / after method execution
- transform the result returned from a function
- transform the exception thrown from a function
- extend the basic function behavior
- completely override a function depending on specific conditions (e.g., for caching purposes)
▼AOP
더보기
AOP
관점 지향 프로그래밍은 모듈성을 증가시키는 것이 목적인 프로그래밍 패러다임을 말한다.
AOP가 필요한 상황
- 모든 메서드의 호출 시간을 측정하고 싶다면?
- 공통 관심 사항(cross-cutting concern) vs 핵심 관심 사항(core concern)
회원 가입, 회원 조회 기능이 로직을 수행하는데 시간이 얼마나 걸리는지 측정하기 위해서 각 메서드 안에 시간 측정하는 로직을 추가해야 할까? 시간 측정하는 로직이 핵심 관심 사항일까? 즉 시간을 측정하는 로직은 공통 관심 사항이고, 이 기능이 핵심 비즈니스 로직과 섞이게 되면 유지보수가 어렵다.
즉 인터셉터는 각각의 핵심 기능을 횡단하면서 재사용성이 가능한 기능들을 관점 지향적으로 하나의 모듈로 묶는 것을 말한다.
여태 미들웨어, 파이프, 가드를 배웠고 이제 인터셉터도 배우는데 그럼 요청이 왔을 때 어떤 순서로 진행되는지 점점 혼란스러워진다. NestJS의 Request lifecycle을 보면 다음과 같다.
- 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
더 요약하자면 요청이 들어온 이후 미들웨어 → 가드 → 인터셉터(pre-controller) → 파이프 → 컨트롤러 → 서비스 → 인터셉터(post-request) → 응답 / 에러가 발생한다면 예외필터
문서에 나온 코드로 예시를 들자면 다음과 같다.
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...'); // <--- pre-controller
const now = Date.now();
return next
.handle()
.pipe(
tap(() => console.log(`After... ${Date.now() - now}ms`)), // <-- post-request
);
}
}
인터셉터는 @UseInterceptors() 데코레이터를 이용하여 컨트롤러에 적용할 수 있다.
728x90
LIST
'개발자 도전기 > [STUDY] JS || TS' 카테고리의 다른 글
NestJS | Repository pattern (0) | 2023.03.05 |
---|---|
NestJS | NestJS와 DB 연결, 환경 변수 설정, DTO, 회원가입 기능 구현 (1) | 2023.02.27 |
NestJS | docs | Guards (0) | 2023.02.24 |
NestJS | docs | Pipes (0) | 2023.02.23 |
NestJS | docs | Exception filters (0) | 2023.02.17 |
댓글