plainToInstance 사용 경험

InnomDB·2022년 5월 10일
0

class-transform

목록 보기
1/1

class-tranform

Model Mapper란?
   어떤 Object(Source Object)에 있는 필드 값들을 자동으로 원하는 Object(Destination Object)에 Mapping시켜주는    라이브러리이다.

타입스크립트에서 model mapper는 class-transform이 있다. 링크 상단에 repository주소를 달아놓았다. 기초 사용법은 링크에서 배우고 내가 다룰 것은 plainToInstance와 excludeExtraneousValues옵션이다.

우선 plainToInstance부터 살펴보면 헛점이 많다고 생각된다. plainToInstance는 plain type의 object를 class type로 Mapping한다. 허나, 이 class가 모든 property를 보장해주진 못한다.

나의 예시를 살펴보면 DB에서 받아오는 값에서 몇 가지의 property를 제거하고 사용하고 싶어 plainToInstance를 사용하였는데 이상하게 class에 정의하지 않은 값이 들어와 헤맨 경험이 있다.
원인을 살펴보니 DB에서 받아오는 값들을 모두 Mapping해주어야 했다.

예를 들어 DB에서 받아오는 값은
{
  @Expose()
  name: 키키,
  age: 20
}

class User {
  name: string
}

plainToInstance(User, obj)의 결과는 age까지 같이 출력된다.
age를 원하지 않는다면 class안에서 @Exclude를 붙인 프로퍼티를 만들어줘야한다.

이것을 코드 단계에서 막는 옵션이 있는데 그것이 바로 excludeExtraneousValues이다.
이제 excludeExtraneousValues 옵션을 언제 써야되고 언제 쓰지 말아야할지에 대해 얘기해볼려고 한다.
excludeExtraneousValues는 class에서 @Expose / @Exclude를 제외한 모든 값들을 제거하는 옵션이다.

plainToInstance(User, obj, { excludeExtraneousValues: true })를 사용하면 age는 데코레이터가 정의되지 않은 미지의 값이기 때문에 제거가 된다. 하지만 이 옵션을 또 사용하면 안되는 경우가 있다. 바로 class에서 다른 entity를 받아올 때이다.

{
  @Expose()
  name: 키키,
  age: 20
  pet: {
           name: 애옹
           sex: 수컷
           }
}

class Cat {
   name: string;
   sex: strng;
}

Class User {
  @Expose()
  name: string;
  @Expose()
  pet: Cat;
}

위의 경우 plainToInstance(User, obj, { excludeExtraneousValues: true })를 하면
예상되는 결과는
{
  name: 키키
  pet: {}
}

이유는 바로 CatEntity에 @Expose를 안해주었기 때문이다. 이처럼 참조하는 class가 원본을 바꿔버려야되는 상황이 생길 수도 있다. 그래서 나는 잘 쓰지 않는다.

또한, 애초에 class에 받아오는 데이터를 명확히 명시해주는게 다른 사람이 보았을 때 무슨 데이터가 있는지 한 눈에 알 수 있으므로 모든 데이터 타입을 명시해주는것이 좋을 것 같다.

위에서 pet: {} 가 나오는 이유는 코드를 살펴보니 대충
classTransformer.plainToInstance(classType, data, params) ---> executor.transform(undefined, plain, cls, undefined, undefined, undefined);
----> defaultMetadataStorage.getExposedProperties(target, this.transformationType) ----> return keys 요런 흐름이라 getExposedProperties여기서 @Expose 데코가 없어서 keys에 포함되지 못하는것 같다.

링크를 타고 들어가 코드를 살펴보면 이해가 더 쉬울 것이다.

profile
이노오오옴

0개의 댓글