먼저 NestJS 요청 생명 주기에 관한 기반 지식이 필요합니다. 여기를 클릭해서 보실 수 있습니다.
Interceptor
인터셉터는 메소드 실행 전후에 추가 로직을 바인딩 합니다. 인터셉터는 다음과 같은것들을 수행할 수 있습니다.
함수에서 반환된 결과 변환
함수에서 던져진 예외를 변환
기본 함수 동작 확장
특정 조건에 따라 함수를 완전히 재정의합니다
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`)),
);
}
}
공식문서의 로깅 인터셉터 예제를 통해 인터셉터가 어떻게 동작하는지 알아보겠습니다. 먼저 위 처럼 인터셉터를 구현합니다.
@Controller('cats')
@UseInterceptors(LoggingInterceptor)
export class CatsController {
constructor(private readonly catsService: CatsService) {}
@Get()
@UseFilters(HttpExceptionFilter)
getAllCat() {
console.log('1');
return 'all cats';
}
그리고 인터셉터를 컨트롤러 레벨에 적용 시키고 요청을 보내봅니다.
pre-controller 단계의 인터셉터가 작동해서 콘솔에 Before가 출력됐고, 컨트롤러의 함수가 실행되어 1이 출력되었습니다.
그 후 post-request 단계의 인터셉터가 작동해서 콘솔에 After... 1ms가 출력 되었습니다.
그 아래의 Log [HTTP] ::1 GET 200 /cats 라인은 일전에 만들었던 로깅 미들웨어입니다. res.on 메소드를 사용해서 응답이 완료 되었을 때만 출력 하도록 하였으므로 요청 생명 주기의 마지막 단계인 응답과 동시에 출력된 것입니다.
SuccessInterceptor 구현해보기
@Get()
@UseFilters(HttpExceptionFilter)
getAllCat() {
return { cats: 'all cats' };
}
// cats.controller.ts
import {
CallHandler, ExecutionContext, Injectable, NestInterceptor
} from '@nestjs/common';
import { map, Observable } from 'rxjs';
@Injectable()
export class SuccessInterceptor implements NestInterceptor {
intercept(
context: ExecutionContext,
next: CallHandler<any>,
): Observable<any> | Promise<Observable<any>> {
return next.handle().pipe(
map((data) => ({
success: true,
data,
})),
);
}
}
SuccessInterceptor는 pre-controller 단계에서는 아무 작업도 하지 않고 post-request 단계에서 응답을 변환하는 인터셉터입니다.
{
"success": true,
"data": {
"cats": "all cats"
}
}
API의 응답 결과를 보면 컨트롤러 구현부에는 없던 success 속성이 SuccessInterceptor에 의해 생성된 것을 확인할 수 있습니다.
pre-controller 단계에 로직 바인딩이 필요한 경우엔 미들웨어를 이용하고, 일반적으로 Interceptor는 응답 결과를 변환하는 용도로 많이 사용한다고 함.
'개발 공부 > NestJS' 카테고리의 다른 글
인 메모리 데이터베이스, Redis (1편) (0) | 2023.03.26 |
---|---|
Serialize 직렬화 (0) | 2023.03.23 |
파이프 Pipe (0) | 2023.03.19 |
예외 필터 Exception filter (0) | 2023.03.19 |
미들웨어 Middleware (0) | 2023.03.19 |