Interceptor(인터셉터)란 무엇일까?
공식문서를 통해 확인해 보면 NestInterceptor 인터페이스를 구현하는 @Injectable() 데코레이터가 달린 클래스를 말한다.
Interceptor는 AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)에서 영감을 받아 만든 다양한 기능을 가진 집합이라고 정의하며 interceptor로 가능한 작업은 다음과 같다고 설명한다. (AOP에 대해서는 따로 포스팅하도록 하겠다)
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();
이외에도 응답을 하나의 양식으로 만들어 클라이언트로 동일한 양식을 가진 응답이 전송될 수 있도록 만들 수도 있다.
즉, 어떻게 응용하느냐에 따라 사용 방법은 무궁무진해질 수 있다는 것이다.