얼마 전 본 서버에서 다른 서버로 User 정보를 보내야 할 일이 있었는데 다른 서버에서 받아보니 entity상에서 Exclude한 정보가 포함되어 있었고 본 서버에서 api를 통해 프론트로 User값을 전달할 때는 발생하지 않았는데 왜 이런 일이 발생하는지 찾아보다가 공식문서를 통해 Serialization(직렬화)에 대한 동작원리를 놓치고 사용하고 있었던걸 파악하고 Serialization에 대해 공부한 내용을 정리한다!!
Serialization이란??
직렬화는 네트워크 응답에서 개체가 반환되기 전에 발생하는 프로세스로 클라이언트에게 반환될 데이터를 변환하고 삭제하기 위한 규칙을 제공하는 것
네스트 공식 문서
네스트는 이러한 작업을 간단히 수행할 수 있도록 하는 기본 기능 ClassSerializerInterceptor 인터셉터를 제공한다. 이는 강력한 클래스 변환기 패키지(class-transformer)를 사용하여 객체를 변환하고 확장 가능한 방법을 제공한다.
import { Exclude } from 'class-transformer';
export class UserEntity {
id: number;
firstName: string;
lastName: string;
// 이런식으로 entity에 class-tranformer에 데코레이터를 사용해서
// return 데이터에 존재하는 password를 제외할 수 있다
@Exclude()
password: string;
}
가장 핵심은 공식에 나오듯 serialization(직렬화)는 네트워크 응답에서 개체가 반환되기 전에 발생한다는 것이고, 이를 위해 인터셉터를 사용한다는 것인데 Nestjs lifeCycle상 인터셉터는 밑에 이미지에 나오듯 Route Handler에 도달하기전 그리고 Route Handler가 끝난후에 적용된다
난 이걸 놓치고 entity에 적용했기 때문에 Typeorm상 데이터를 return 받을 때부터 적용된다고 착각을 하고 있었고, 그런 상태로 Controller안 service상에서 User 데이터를 다른 서버로 보내고 있었으니 당연히 인터셉터를 거치지 못해 내가 제외한 데이터들이 살아있었던 것이다!!.. 이 후 나는 내가 숨기고자 하는 데이터를 코드 상에서 삭제 후 다른 서버로 보내 문제를 해결했다.
번외
Typeorm에서 데이터 값을 받아 오는 순간부터 해당 데이터를 지우고 싶다면 아래와 같이 @Column({select: false}) 컬럼 옵션을 줄 때 부터 select:false로 제외 할 수 있다.
// user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm'
@Entity({name: 'users'})
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({unique: true})
username: string;
// This column will not be selected by find functions and QueryBuilder
@Column({select: false})
password: string
}
정리
지금 회사에서 Nestjs를 사용해서 개발하고 있지만 Nest에서 제공해주는 서비스나 기능들에 대한 핵심개념과 동작원리에 대해 파악하면서 사용해야 겠다!!
'개발 > NestJS' 카테고리의 다른 글
[NestJS] CORS 설정과 주의할 점(preflight) (0) | 2022.11.26 |
---|---|
[NestJs] 순환 종속성(Circular Dependency) 에러 (0) | 2022.10.23 |
TypeError: Class extends value undefined is not a constructor or null (0) | 2022.09.27 |
npm install vs npm ci (0) | 2022.09.21 |
[NestJS] Naver SMS 인증 서버 구현 (0) | 2022.08.23 |
댓글