@Injectable() 데코레이터를 사용하고 NestInterface를 구현해서 만든다.
@Injectable() 데코레이터를 사용하는거 보면 얘도 프로바이더.

Aspect Oriented Programming 기법을 사용하여 아래를 수행할 수 있다.
NestInterface의 intercept(context: ExecutionContext, next: CallHandler)을 구현한다.
이 경우 next.handle().pipe()를 반환하는데, 이를 설명하면 다음과 같다.
// route handler 호출 전
return
next.handle() // route handler 호출
// router 종료 후 실행. 아래의 내용이 없다면 라우트 종료 후 실행되는 코드 없음.
.pipe(map((data) => (data === undefined ? null : data)));
이때, pipe에서는 RxJS tap(), map() 연산자를 사용할 수 있다. 둘 다 Observable의 데이터 작업을 수행하지만 차이점은 다음과 같다.
다른 연산자로는 timeout, catchError()이 있다.
return next.handle().pipe(
timeout(5000), // 5000ms, 즉 5초가 지나면 error 발생
catchError(err => { // error가 발생했다면 실행
if (err instanceof TimeoutError) {
return throwError(() => new RequestTimeoutException());
}
return throwError(() => err);
}),
);
더 많은 연산자가 있지만, 이 부분은 공식 문서를 참고하길 바란다.
이곳을 참고하자. 공식 문서의 Overview에는 자세하게 나와있지 않다.
대충 ArgumentsHost 인터페이스를 상속하는데, 클라이언트의 요청 정보를 받아온다 생각하면 될 것 같다.
next 변수는 handle() 메소드를 가지고 있다. 이 메소드가 호출되지 않는다면 라우트 핸들러는 실행되지 않는다.
이 방식은 intercept() 메소드가 req/res 흐름을 효과적으로 감싼다는 것을 의미한다. 결과적으로 최종 라우트 핸들 실행 전/후에 사용자 정의 로직을 넣을 수 있다는 뜻이다!
CallHandler#handle 메소드는 Observable을 반환하므로 옵저버 패턴을 사용한다는 것을 추측할 수 있다. 즉 실행이 되고 값을 수정할 수 있다는 뜻.
해당 반환값은 RxJS 연산자를 통해 응답을 추가로 조작할 수 있다.
handle()이 호출되는 지점을 Pointcut이라고 하는데, 이는 추가 로직이 삽입되는 지점임을 알린다.
@UseInterceptors(<Interceptor>)app.useGlobalInterceptors(new <Interceptor>());@Module({
providers: [
{
provide: APP_INTERCEPTOR,
useClass: LoggingInterceptor,
},
],
})
export class AppModule {}
provide만 다르지 사용법은 다 같다.