NestJS - Custom Validator

2025. 1. 27. 00:24·Node/NestJS
반응형

이번 포스팅에서는 NestJS에서 class-validator를 사용해서 나만의 Custom Validator를 만드는 방법에 대해 알아보고자 한다.

 

< 목차 >

  1. class-validator
  2. Custom Validator 만들기

 

 

1. class-validator

우선 class-validator는 NestJS에서만 사용할 수 있는 것이 아니다. TypeScript를 사용하기만 한다면 어디서든 사용할 수 있는 라이브러리이다. 실제 어떤 식으로 class-validator를 사용해서 클래스를 검증하는지 살펴보자.

https://www.npmjs.com/package/class-validator

 

class-validator

Decorator-based property validation for classes.. Latest version: 0.14.1, last published: a year ago. Start using class-validator in your project by running `npm i class-validator`. There are 6343 other projects in the npm registry using class-validator.

www.npmjs.com

import { validate, IsNotEmpty, IsEmail } from 'class-validator';

class User {
    @IsNotEmpty()
    name: string;

    @IsEmail()
    email: string;
}

const user = new User();
user.name = '';
user.email = 'helloWorld';

validate(user).then(errors => {
    // 에러 반환
});

위와 같이 특정 클래스의 프로퍼티를 검증하고 싶은 경우 class-validator에서 제공해주는 어떤 validator든 검증하고 싶은 프로퍼티에 데코레이터 형태로 제공해주면 된다. class-validator는 IsNotEmpty, IsEmail, IsInt, IsString 등 직관적이고 우리가 쉽게 알 수 있는 이름으로 annotation들을 제공해주고 있다. 그리고 validate() 함수를 사용해 객체를 검증했을 때 class-validator에 부합하지 않은 값이 입력됐다면 해당되는 에러를 반환하게 된다.

👉 class-validator 반환 에러 구조

  • target : 검증한 객체
  • property : 검증 실패한 프로퍼티
  • value : 검증 실패한 값
  • constraints : 검증 실패한 제약조건
  • children : 프로퍼티의 모든 검증 실패 제약조건
{
    target: Object;
    property: string;
    value: any;
    constraints?: {
      [type: string]: string;
    };
    children?: ValidationError[];
}

👉 NestJS에서 class-validator 적용하기

실제 NestJS에서 class-validator를 적용하기 위해서는 우선 class-validator와 class-transformer 패키지를 설치해준다.

$ npm i --save class-validator class-transformer

설치한 class-validator를 사용하기 위해서는 src/main.ts 파일에서 다음과 같이 ValidationPipe를 등록해주면 된다. (ValidationPipe에서 class-validator 와 class-transformer를 사용하기 때문에 두 패키지를 반드시 설치해줘야 한다)

// 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 uses the class-validator and class-transformer libraries
    app.useGlobalPipes(
        new ValidationPipe({
            whitelist: true,
            forbidNonWhitelisted: true,
        }),
    );
    await app.listen(process.env.PORT ?? 3000);
}
bootstrap();
ValidationPipe() 옵션
->  whitelist : DTO에서 데코레이터가 명시된 프로퍼티만 허용하고 나머지 프로퍼티들은 자동으로 제거
->  forbidNonWhitelisted : whitelist 옵션을 사용한 상태에서 DTO에 정의되지 않은 프로퍼티가 들어오면 Exception 발생

 

다음은 알아두면 유용한 기본 제공 class-validator들이다.

👉 공통 Validator

  • @IsDefined
  • @IsOptional
  • @Equals
  • @NotEquals
  • @IsEmpty
  • @IsNotEmpty
  • @IsIn
  • @IsNotIn

👉 타입 Validator

  • @IsBoolean
  • @IsDate
  • @IsDateString
  • @IsString
  • @IsNumber
  • @IsInt
  • @IsArray
  • @IsEnum

👉 숫자 Validator

  • @IsDivisibleBy
  • @IsPositive
  • @IsNegative
  • @Min
  • @Max

👉 문자 Validator

  • @Contains
  • @NotContains
  • @IsAlphanumeric
  • @IsCreditCard
  • @IsHexColor
  • @MaxLength
  • @MinLength
  • @IsUUID
  • @IsLatLong

 

 

 

2. Custom Validator 만들기 

앞서 class-validator에서 기본으로 제공해주는 validator들을 살펴보았다. 하지만 이 validator들이 항상 우리 입맛에 맞을 수는 없다. 그럴 때는 나만의 Custom Validator를 직접 만들어서 사용하는 것이 꽤 유용하다.

 

class-validator에서 가져온 ValidatorConstraintInterface를 implements 하여 PasswordValidator 같은 나만의 validator를 만들 수 있다. 그리고 이렇게 만든 PasswordValidator 클래스에 @ValidatorConstraint() annotation을 붙여줌으로써 해당 클래스를 validator로 사용 가능하다. Custom Validator를 적용할 때는 class-validator에서 가져온 @Validate() annotation의 인수로 validator를 전달해주면 된다.

import {
    Validate,
    ValidationArguments,
    ValidatorConstraint,
    ValidatorConstraintInterface,
} from 'class-validator';

// Custom Validator
@ValidatorConstraint()
class PasswordValidator implements ValidatorConstraintInterface {
    validate(value: any, validationArguments?: ValidationArguments): Promise<boolean> | boolean {
        // 비밀번호 길이는 4~8
        return value.length >= 4 && value.length <= 8;
    }

    defaultMessage?(validationArguments?: ValidationArguments): string {
        return '비밀번호의 길이는 4~8자여야 합니다. 입력된 비밀번호: ($value)';
    }
}

// Custom Validator 적용
class CreateUserDto {
    @Validate(PasswordValidator)
    password: string;
}

PasswordValidator라는 나만의 Custom Validator를 만들고 @Validate() annotation의 인수로 전달해주는 방식 외에도 @Validate(PasswordValidator)를 하나로 묶어주는 IsValidPassword라는 커스텀 데코레이터 함수를 만들어서 좀 더 편하고 쉽게 사용할 수도 있다. 이 때 registerDecorator를 사용해 Custom Validator를 validator로 등록해 함수를 만들어주면 된다.

import {
    registerDecorator,
    ValidationOptions,
} from 'class-validator';

function IsValidPassword(validationOptions?: ValidationOptions) {
    return function (object: Object, propertyName: string) {
        registerDecorator({
            target: object.constructor,
            propertyName,
            options: validationOptions,
            validator: PasswordValidator, // validator로 Custom Validator 등록
        });
    };
}

// IsValidPassword 적용
class CreateUserDto {
    @IsValidPassword()
    password: string;
}

 

 

 

 

 

반응형

'Node > NestJS' 카테고리의 다른 글

NestJS - MongoDB 연결하기 & 환경 변수 설정  (0) 2023.04.08
NestJS - Pipes & Interceptors  (0) 2023.03.26
NestJS - Exception filter 설정  (0) 2023.03.16
NestJS - LoggerMiddleware 설정  (0) 2023.03.13
NestJS - 캡슐화(Encapsulation) & Modules  (0) 2023.03.10
'Node/NestJS' 카테고리의 다른 글
  • NestJS - MongoDB 연결하기 & 환경 변수 설정
  • NestJS - Pipes & Interceptors
  • NestJS - Exception filter 설정
  • NestJS - LoggerMiddleware 설정
bitkunst
bitkunst
Ever tried, Ever failed, No matter. Try again, Fail again, Fail better.
  • bitkunst
    THE DEVELOPER
    bitkunst
  • 전체
    오늘
    어제
  • bitkunst GitHub
    • 분류 전체보기 (154)
      • Setup (1)
      • HTML (7)
      • CSS (10)
      • Go (2)
      • JavaScript (14)
      • TypeScript (3)
      • Node (34)
        • Node.js (7)
        • Express (19)
        • NestJS (8)
      • React (19)
      • MySQL (6)
      • BlockChain (14)
      • Ethereum (20)
      • AWS (5)
      • Linux (2)
      • Infra (2)
        • Docker (2)
      • Testing (2)
      • ABOUT CS (11)
      • 토이 프로젝트 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    이더리움 스마트 컨트랙트
    nestJS
    리액트
    프론트엔드
    Blockchain
    이더리움
    AWS
    Nest
    웹프론트엔드
    웹
    타입스크립트 블록체인 만들기
    블록체인 트랜잭션 만들기
    JavaScript
    AWS EC2
    CSS Style
    Ethereum
    타입스크립트로 블록체인 만들기
    nodejs mysql
    html
    블록체인
    타입스크립트 블록 체인
    웹개발
    TypeScript Blockchain
    타입스크립트로 블록 체인 만들기
    블록체인 지갑 서버 만들기
    자바스크립트
    redux
    Nodejs
    css
    React
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.1
bitkunst
NestJS - Custom Validator
상단으로

티스토리툴바