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으로 내보내자.
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에서 명시한 데이터아니면 무시
}),
);
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