반응형
Class Validator
Class Validator는 NestJS에서 데이터 유효성 검사를 수행하기 위해 사용하는 유효성 검사 라이브러리
DTO(Data Transfer Object)와 함께 사용되어, 데이터의 구조와 유효성을 정의하고, 요청 데이터를 자동으로 검증한다.
- 데코레이터 기반 검증
- 검증 규칙을 정의하는 데 데코레이터를 사용함
- 필드 수준에서 적용하며, 다양한 유효성 검사 규칙을 제공
- DTO와 함께 사용
- 클라이언트 요청 데이터를 특정 DTO 클래스로 매핑하여 검증
- NestJS의 파이프와 연동
- ValidationPipe 를 사용하면 요청 시 데이터 검증이 자동으로 수행된다
설치 방법
npm install class-validator
주요 데코레이터
Decorator | 설명 |
@IsString() | 문자열인지 확인 |
@IsInt() | 정수인지 확인 |
@IsEmail() | 유효한 이메일 형식인지 확인 |
@IsOptional() | 해당 필드가 선택적인지 확인 |
@Min(value) | 숫자 값이 최소값 이상인지 확인 |
@Max(value) | 숫자 값이 최대값 이하인지 확인 |
@Length(min, max) | 문자열 길이가 최소, 최대값 범위 내에 있는지 확인 |
@Matches(regex) | 주어진 정규식과 일치하는지 확인 |
@IsEnum(enum) | 값이 특정 열거형(Enum) 값 중 하나인지 확인 |
@IsArray() | 배열인지 확인 |
@ArrayMinSize(size) | 배열의 최소 길이를 검증 |
ValidationPipe 설정
- ValidationPipe를 글로벌 또는 특정 경로에서 설정하면, DTO를 자동으로 검증
main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ValidationPipe } from '@nestjs/common';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
// 글로벌 ValidationPipe 설정
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
create-post.dto.ts
import { IsString } from 'class-validator';
export class CreatePostDto {
@IsString() // 해당 속성이 문자열인지 확인하는 데코레이터
title: string;
@IsString()
content: string;
}
DTO 를 이용해서 간결한 코드를 만들 수 있다.
PickType 활용
Typescript 에서 제공하는 유틸리티인 Pick 을 이용하면 DTO 를 모델에 상속을 시킬 수 있다.
하지만 그냥 Pick을 사용하면 타입을 반환하기 때문에 값이 필요한 DTO에서 상속이 불가능하다.
Pick vs PickType
기능 | Pick | PiccType |
목적 | 인터페이스 또는 타입에서 속성을 선택 | 클래스에서 속성을 선택 |
사용 환경 | 타입스크립트 일반적인 타입 시스템 | NestJS의 DTO 또는 클래스 기반 설계 |
리플렉션 메타데이터 | 지원하지 않음 | 지원 (Swagger와 같은 NestJS 툴에서 활용 가능) |
사용 예시 | Pick<Type, Keys> | PickType(Class, Keys as const) |
import { IsOptional, IsString } from 'class-validator';
import { PostsModel } from '../entity/post.entity';
import { PickType } from '@nestjs/mapped-types';
export class CreatePostDto extends PickType(PostsModel, ['title', 'content']) {}
- 위와 같이 PickType을 이용해서 extends 를 해야한다.
Class Transformer
Class Transformer는 객체를 변환하거나, 직렬화 및 역직렬화를 통해 플레인 자바스크립트 객체(Plain Object)와
클래스 인스턴스 간의 변환을 쉽게 수행하도록 도와주는 도구이다.
이는 주로 데이터를 정리하거나, 유효성 검사와 직렬화를 위해 사용된다
npm install class-transformer
주요 데코레이터
- @Expose / @Exclude
- 직렬화 시 포함하거나 제외할 프로퍼티를 정의함
- @Transform
- 특정 프로퍼티를 변환하기 위한 로직을 정의함
- @Type
- 프로퍼티가 클래스 타입인 경우 타입을 지정해 변환을 도와줌
장점
- 데이터 정제: API 요청/응답 데이터 정제 및 변환을 쉽게 처리.
- 유효성 검사와 결합: class-validator와의 조합으로 안전한 데이터 처리가 가능.
- 직렬화 최적화: 불필요한 데이터를 자동으로 제외하거나 필요한 형태로 가공.
@Exclude 사용예시 : 비밀번호 정보 포함된 데이터 문제
- getUser() 함수의 역할
- getUser() 함수는 데이터베이스에서 유저 정보를 조회하여 반환한다.
이때 반환되는 객체에는 모든 유저 정보(예: 이름, 이메일, 비밀번호 등)가 포함되고 있다.
- getUser() 함수는 데이터베이스에서 유저 정보를 조회하여 반환한다.
- 비밀번호 포함 문제
- API 응답으로 비밀번호가 포함된 데이터가 클라이언트에 전달된다면, 이는 보안상 심각한 문제가 된다.
비밀번호와 같은 민감한 정보는 절대 사용자에게 노출되어서는 안됨
- API 응답으로 비밀번호가 포함된 데이터가 클라이언트에 전달된다면, 이는 보안상 심각한 문제가 된다.
- select 옵션으로 비밀번호 제외
- @Column({ select: false }) 옵션을 사용해 특정 필드를 기본적으로 쿼리 결과에 포함하지 않도록 설정할 수 있지만
이는 전역적으로 적용되므로, 다른 비즈니스 로직에서 비밀번호가 필요한 경우에도
select: false로 인해 해당 필드를 사용할 수 없게 되는 단점이 있다.
- @Column({ select: false }) 옵션을 사용해 특정 필드를 기본적으로 쿼리 결과에 포함하지 않도록 설정할 수 있지만
- @Exclude로 문제 해결
- @Exclude는 직렬화 단계에서만 동작하기 때문에, 데이터베이스에서 필요한 모든 정보를 가져오되,
클라이언트에 데이터를 반환할 때 민감한 정보를 제외하는 방식으로 문제를 해결할 수 있다.
- @Exclude는 직렬화 단계에서만 동작하기 때문에, 데이터베이스에서 필요한 모든 정보를 가져오되,
user.controller.ts
import { Body, ClassSerializerInterceptor, Controller, Get, Post, UseInterceptors } from '@nestjs/common';
import { UsersService } from './users.service';
@Controller('users')
export class UsersController {
constructor(private readonly usersService: UsersService) {}
@Get()
@UseInterceptors(ClassSerializerInterceptor)
/*
serialization -> 직렬화 -> 현재 시스템에서 사용되는 데이터의 구조를 다른 시스템에서도
쉽게 사용할 수 있는 포맷으로 변환
-> class object에서 JSON으로 변환
deserialization -> 역직렬화
*/
getAllUsers() {
return this.usersService.getAllUsers();
}
}
@Expose() 예시
user.entity.ts
@Expose()
get nicknameAndEmail() {
return this.nickname + '/' + this.email;
}
Expose()를 클래스에도 적용할 수 있다.
@Entity()
@Exclude()
export class UsersModel extends BaseModel {
... // 코드 생략
@Column({
length: 20,
unique: true,
})
@Expose()
nickname: string;
}
- 자체 클래스에 Exclude()를 하고 보여주고 싶은 프로퍼티에 Expose() 하게 되면 원하는 프로퍼티만 출력이 가능하다.
반응형
'nestJS' 카테고리의 다른 글
NestJS | Multer, Static File Serving (0) | 2024.11.26 |
---|---|
NestJS | Guard (0) | 2024.11.20 |
NestJS | Pipe (0) | 2024.11.20 |
NestJS | TypeORM Table Inheritance (0) | 2024.11.12 |
NestJS | TypeORM Entity Embedding (2) | 2024.11.12 |