[Dimelo Project] Class-validator, Class-transformer, Serialize interceptor

Suyeon Pi·2022년 1월 12일
0

Dimelo

목록 보기
6/22
post-custom-banner

return 되는 json 값을 내가 원하는 데이터만 노출 시키고 싶었다.
예를 들어 비밀번호를 노출 시키고 싶지 않으면 Entity에서 @Exclue()나 select: false를 해도되지만, 비밀번호 검증과 같은 함수를 구현할때 다시 비밀번호를 select해서 user정보를 가져와야하는 귀찮음이 있다.

Interceptor와 DTO를 사용해보자.
DTO는 request될 때 class-validator를 통해 데이터 검증도 가능하지만 데이터가 return될 때 class-transformer를 통해 데이터 조작도 가능하다. Interceptor도 마찬가지로 들어오는 data와 나가는 data를 조작할 수 있다.
Interceptor를 통해 user entity의 object instance를 class instance로 바꾸고 return user dto class에서 json으로 serialize할 rule을 정의 한다음 원하는 데이터만 json으로 내보내자.

class-validator

request들어올때 ) class-validator를 통해 json -> object 변환 후 dto에서 validation

// create-user-profile.dto.ts
import { IsNotEmpty, IsOptional, IsString, MaxLength } from 'class-validator';

export class CreateUserProfile {
  @IsNotEmpty()
  @IsString()
  @MaxLength(10)
  nickname: string;

  @IsOptional()
  @IsString()
  imageUrl?: string;

  @IsString()
  @IsNotEmpty()
  job: string;

  @IsNotEmpty()
  @IsString()
  career: string;
}
// main.ts
  app.useGlobalPipes(
    new ValidationPipe({
      transform: true,
      whitelist: true, // dto에서 명시한 데이터아니면 무시
    }),
  );

class-transformer

response로 나갈때 ) user entity -> serialize interceptor -> return user dto -> json

// serialize.interceptor.ts
export class SerializeInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, handler: CallHandler): Observable<any> {
    return handler.handle().pipe(
      map((data: any) => { // data: user entity
        return plainToClass(ReturnUserDto, data, {
          // plainToClass: user entity를 User dto class instance로 변한
          excludeExtraneousValues: true, // dto에서 Expose한 것만 json으로 변환함.
        });
      }),
    );
  }
}
// return-user.dto
import { Expose } from 'class-transformer';

export class ReturnUserDto {
  @Expose() // json으로 노출 시키고자 하는 것만 Expose한다
  id: number;

  @Expose()
  email: string;

  @Expose()
  nickname: string;

  @Expose()
  imageUrl: string;

  @Expose()
  job: string;

  @Expose()
  career: string;

  @Expose()
  introduction: string;
}

https://github.com/typestack/class-validator
https://github.com/typestack/class-transformer

profile
Stay hungry, Stay foolish!
post-custom-banner

0개의 댓글