728x90

1. Interceptor의 역할 이해
Interceptors는 Aspect-Oriented Programming (AOP) 개념을 구현하며, 메서드 실행 전후에 추가적인 로직을 삽입하는 데 사용됩니다. Response Wrapping에서는 주로 응답이 클라이언트로 전송되기 직전에 응답 데이터를 가로채서(intercept) 표준화된 형식으로 포장하는 역할을 합니다.
2. 베스트 프랙티스 추천
1) 응답 구조 표준화 (Standardized Response Format)
성공적인 REST API 응답은 항상 예측 가능한 일관된 구조를 가져야 합니다. 이를 위해 모든 성공 응답을 감싸는 표준 DTO (Data Transfer Object)를 정의합니다.
- 목표: 클라이언트가 200/201 상태 코드에 대해 항상 동일한 구조를 기대하고 파싱할 수 있게 합니다.
- 일반적인 구조 예시:
// src/common/dtos/response.dto.ts
export class ResponseDto<T> {
statusCode: number; // HTTP 상태 코드 (항상 200, 201 등)
message: string; // 성공 메시지 (선택 사항)
data: T; // 실제 반환 데이터 (핵심)
timestamp: string;
}
728x90
2) CallHandler와 map() 연산자를 사용한 Wrapping
Interceptors는 RxJS의 Observable 스트림을 사용하여 응답을 처리합니다. handle() 메서드 내에서 pipe()와 map() 연산자를 사용하여 Controller에서 반환된 실제 응답 데이터를 표준 DTO 안에 넣어 감싸야 합니다.
- 구현: data 필드에 Controller에서 반환된 실제 값을 할당하고, 나머지는 현재의 Context 정보를 활용하여 채웁니다.
// src/common/interceptors/response.interceptor.ts
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { ResponseDto } from '../dtos/response.dto';
@Injectable()
export class ResponseInterceptor<T> implements NestInterceptor<T, ResponseDto<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<ResponseDto<T>> {
const httpContext = context.switchToHttp();
const statusCode = httpContext.getResponse().statusCode; // 응답 코드 가져오기
return next.handle().pipe(
map(data => ({
statusCode: statusCode, // 200, 201 등
message: 'Success',
data: data === undefined ? null : data, // 데이터가 없으면 null 처리
timestamp: new Date().toISOString(),
})),
);
}
}
728x90
3) 전역 Interceptor로 등록 (Global Interceptor)
Response Wrapping Interceptor는 모든 경로에 적용되어야 하므로 전역(Global)으로 등록하는 것이 베스트 프랙티스입니다.
// src/main.ts
import { ResponseInterceptor } from './common/interceptors/response.interceptor';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// Response Interceptor 전역 등록
app.useGlobalInterceptors(new ResponseInterceptor());
await app.listen(3000);
}
bootstrap();
4) 예외 처리와의 통합
Response Wrapping Interceptor는 성공적인 응답(2xx)만 감싸야 합니다. 에러 응답(4xx, 5xx)은 이전에 설정한 전역 예외 필터(Global Exception Filter)에서 처리되므로, Interceptor에서는 catchError를 통해 예외를 별도로 처리할 필요가 없습니다. 이는 역할 분리를 명확하게 합니다.
728x90
'Nest.js를 배워보자 > 10. NestJS에서 REST API 베스트 프랙티스' 카테고리의 다른 글
| NestJS Swagger로 완벽한 API 문서를 만드는 5가지 베스트 프랙티스 (0) | 2025.12.03 |
|---|---|
| NestJS REST API 에러 핸들링 베스트 프랙티스 (0) | 2025.12.03 |
| NestJS REST API 폴더 구조 추천 (0) | 2025.12.03 |