ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • nestjs에서 사용자 정의 validate 구현하기
    카테고리 없음 2024. 6. 13. 17:13
    728x90

    class-validator에서는 많은 validation 조건을 제공하여 줍니다. 하지만 사용자 정의 옵션이 필요할 때가 있는데, 이때 설정이 생각보다 복잡하네요.

    ValidatorConstraintInterface 구현 하기

    class-validator ValidatorConstraintInterface interface를 구현해서 사용자 정의 validation 처리를 합니다.

    아래는 구현된 예제 입니다.

    import { ValidatorConstraint, ValidatorConstraintInterface, ValidationArguments } from 'class-validator';
    
    @ValidatorConstraint({ name: 'customText', async: false })
    export class CustomTextLength implements ValidatorConstraintInterface {
      validate(text: string, args: ValidationArguments) {
        return text.length > 1 && text.length < 10; // for async validations you must return a Promise<boolean> here
      }
    
      defaultMessage(args: ValidationArguments) {
        // here you can provide default error message if validation failed
        return 'Text ($value) is too short or too long!';
      }
    }
    

    사용 예제

    아래는 Post 클래스의 사용자 정의 validate를 사용하는 예제입니다.

    import { Validate } from 'class-validator';
    import { CustomTextLength } from './CustomTextLength';
    
    export class Post {
      @Validate(CustomTextLength, {
        message: 'Title is too short or long!',
      })
      title: string;
    }
    

    nestjs에 적용 하기

    위와 같이 설정 후 @Injectable을 사용하면 오류를 확인 할 수 있습니다. How to inject service to validator constraint interface in nestjs using class-validator?를 참고 하면 아래와 같은 컨테이너 처리를 추가 해야 합니다.

    // Custom Validate
    import {ValidatorConstraint, ValidatorConstraintInterface} from 'class-validator';
    import {UsersService} from './user.service';
    import {Injectable} from '@nestjs/common';
    
    @ValidatorConstraint({ name: 'isUserAlreadyExist', async: true })
    @Injectable() // this is needed in order to the class be injected into the module
    export class IsUserAlreadyExist implements ValidatorConstraintInterface {
        constructor(protected readonly usersService: UsersService) {}
    
        async validate(text: string) {
            const user = await this.usersService.findOne({
                email: text
            });
            return !user;
        }
    }
    
    // UserModule 
    import {Module} from '@nestjs/common';
    import { UsersController } from './user.controller';
    import { UsersService } from './user.service';
    import { IsUserAlreadyExist } from './user.validator';
    
    @Module({
        controllers: [UsersController],
        providers: [IsUserAlreadyExist, UsersService],
        imports: [],
        exports: []
    })
    export class UserModule {
    }
    
    // main.ts
    async function bootstrap() {
      const app = await NestFactory.create(AppModule);
      useContainer(app.select(AppModule), { fallbackOnErrors: true });
    ...}
    

    위와 같이 설정하면 inject이 정상적으로 처리 되는 것을 확인 할 수 있습니다.

    약간 복잡해 보이는 설정인데, 한줄씩 코드로 보면 어렵지 않습니다.

    참고 자료

    728x90
Designed by Tistory.