본문 바로가기

class-validator 커스터마이징 본문

개발/nest.js

class-validator 커스터마이징

자전하는명왕성 2023. 11. 30. 10:29

먼저 class-validator란, 자바스크립트 또는 타입스크립트에서, 객체의 유효성을 검사하고 검증하는데 도움을 주는 라이브러리다.

이를 사용하면 다양한 유효성 검사 규칙을 정의하고 이를 객체에 적용할 수 있다는 장점이 있다. (예를 들어, 이메일 주소가 올바른 형식인지 확인하거나 비밀번호가 일치하는지 확인하는 등의 검증 규칙을 정의할 수 있다.)

 

아래는 class-validator를 사용하여, user DTO인 nickname의 길이가 1에서 50 사이인지 검증하는 것을 보여준다.

nickname의 길이가 규정한 1보다 작거나, 50보다 클 경우 'Bad Request' 에러를 자동적으로 반환한다.

import { Field, InputType } from '@nestjs/graphql';
import { Length } from 'class-validator';

@InputType()
export class CreateUserInput {
  @Field(() => String)
  @Length(1, 50)
  nickname: string;
}

 

위에서 사용한 Length 라는 메서드 말고도 다양한 메서드가 존재하지만, 직접 만들어야 할 경우가 있는데 당연하게도 class-validator에 내가 원하는 검사 조건이 없는 경우다.

내 경우는 nickname이 '  aa '와 같이 양쪽으로 공백이 들어가는 경우를 불용하고 싶었고, 이를 직접 커스터마이징하여 만들었다.

그리고 그 코드는 다음과 같다.

정규표현식으로 양쪽 공백 여부를 검증하고, 오류 시 내보낼 메시지도 설정할 수 있다. 

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

export function NoWhitespace(validationOptions?: ValidationOptions) {
  return function (object: object, propertyName: string) {
    registerDecorator({
      name: 'noWhitespace',
      target: object.constructor,
      propertyName: propertyName,
      options: validationOptions,
      validator: {
        validate(value: any) {
          if (typeof value !== 'string') {
            return true; // 다른 유효성 검사 데코레이터에서 처리하도록 true 반환
          }
          return !/^\s|\s$/.test(value); // 양쪽 공백 여부 검증
        },
        defaultMessage(validationArguments?: ValidationArguments) {
          return '문자열은 양쪽에 공백을 포함할 수 없습니다.'; // 에러 메시지 커스텀
        },
      },
    });
  };
}

 

그리고 아래와 같이 적용해주면, 내가 원한 바와 같이 양쪽 공백을 불용하는 검사 조건을 적용할 수 있게 된다.

import { Field, InputType } from '@nestjs/graphql';
import { Length } from 'class-validator';
import { NoWhitespace } from 'src/common/filter/custom-class-validator';

@InputType()
export class CreateUserInput {
  @Field(() => String)
  @Length(1, 50)
  @NoWhitespace()
  nickname: string;
}

 

Comments