프로젝트를 진행하면서 Response를 JSON API형태에 맞추어 내보내는걸 신경쓰며 개발을 진행하였습니다.
이것 이외에도 다른 규칙들이 많지만 최상위 구성원을 맞추기위해선 data로 한번 감싸야하는 작업이 진행됩니다.
때문에 이전코드는 다음 코드와 같습니다.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
}
@Injectable()
export class TransformInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(map(data => ({ data })));
}
}
Interceptor로 모든 데이터를 { data } 로 감싸서 리턴하게 되는데 가끔 다른 데이터를 사용할 경우 곤란해지는 경우가 있었습니다.
이를 좀 간편하게 특정 데이터(link, meta ...)는 있을경우와 data만 보낸경우 로직을 다르게 처리 하도록 작업하였습니다.
결과 코드는 다음과 같습니다.
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
export interface Response<T> {
data: T;
[key: string]: any;
}
const jsonFilter = ['link', 'metadata'];
@Injectable()
export class TransformInterceptor<T = any> implements NestInterceptor<T, Response<T>> {
private isObject = (data: any): data is Record<string, any> =>
typeof data === 'object' && data !== null;
private handleResponse = (data: T): Record<string, any> => {
const res: Record<string, any> = { data: {} };
Object.keys(data).forEach(key => {
if (jsonFilter.includes(key)) {
res[key] = data[key];
} else {
res.data[key] = data[key];
}
});
return res;
};
private handleObjectData = (data: T): Response<T> => {
const res = this.handleResponse(data);
return res as Response<T>;
};
private handleNonObjectData = (data: T): Response<T> => ({ data });
private handleData = (data: T): Response<T> =>
this.isObject(data) ? this.handleObjectData(data) : this.handleNonObjectData(data);
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(map(this.handleData));
}
}
1. intercept에서 실행되는것은 handleData로 next에서 넘어온 Observable을 인자로 넘어온 data를 넘겨받습니다.
2. 해당 데이터가 Object인지 검사합니다 => 이렇게 한 이유는 단순히 data만 넘기는 경우 알아서 data를 감싸주는 원래의 기능을 유지하기 위해서입니다.
3. object인 경우 jsonFilter에 해당하는 값은 res에 key값으로 맞추어 작성, 아닌값은 data로 작성
4. object가 아닌경우 data로 감싸 리턴합니다.
이렇게 작성시 결과
임시로 이러한 데이터를 내보낸다 했을시
이런식으로 작동 합니다.
아직 코드에 부족한점이 많아 리팩토링을 도전해볼 예정입니다. 더 나은 코드가 있다면 댓글 남겨주시면 감사하겠습니다.
'개발' 카테고리의 다른 글
[ 개발 ] 자바스크립트 동작 원리 (0) | 2024.04.01 |
---|---|
[ Node.js ] 메일 전송 실패 에러 (nodeMailer) (2) | 2023.11.30 |
[ Nest.js ] Custom Exception 관리하기 (0) | 2023.10.21 |
[ 공식문서 ] 공식문서 링크 모으기 (0) | 2023.10.09 |
[ 프로젝트 세팅 ] Nest.js + Husky + CommitLint + Gitmoji 세팅 (0) | 2023.09.12 |
댓글