class-validator : @ValidateIf

ARA JO·2021년 6월 11일
1

Nest

목록 보기
1/3
post-thumbnail

class-validator : @ValidateIf

export class CreateBaristaDto{
  @IsString()
  readonly name: string

  @ValidateIf(b=>b.name==='test1')
  @IsString()
  readonly test: string
  ...
}

case1: isString 인데 number로 넘겨줘도 돌아간다?!

{
	"name":"test1",
	"test":1,
	"brand": 7,
	"profile": {
		"photo": "ara.jpg",
		"skills": "steam"
	}

}

enableImplicitConversion

global pipe 에 validationPipe를 살펴보자. 원인은 그 안에 있었다!

main.js

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {ValidationPipe} from "@nestjs/common"

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.useGlobalPipes(new ValidationPipe({
    whitelist:true,
    forbidNonWhitelisted:true,
    transform:true,
    transformOptions:{
      enableImplicitConversion:true, //dto마다 @Type을 지정해 줄 필요가 없다.
    }
  }))
  await app.listen(3000);
}
bootstrap();

enableImplicitConversion: true

해당 속성이 true인 경우 묵시적 형변환을 허용한다. 그렇다면 정확한 타입 검사를 위해서 false로 하는게 나을까? 그건 또 아니다. 예를들어 sql은 항상 string으로 변환되는데 이를 하나하나 처리해주는 것은 매우 귀찮은일이다. 다만, enum 같은 경우에 확실하게 사용할 수 있다.

@IsBoolean()을 쓸 때 주의해야할 점

"2", "true", 0 이런 값... 심지어 "aaaaa"와 같은 값도 다 문제없이 들어간다. 정확한 validation이 되지 않는다. -> 값있으면 true, 없으면 0이 되는 것 같다.

단지 null에 대해서만 "test2 must be a boolean value" 에러 반환

export class CreateBaristaDto{
  @IsString()
  readonly name: string

  @ValidateIf(b=>b.name==='test1')
  @IsString()
  readonly test: string

  @IsBoolean()
  readonly test2: boolean
  
 // ...
}

enableImplicitConversion: true 인 경우

값이 null일 때

값이 "aaaa" 일 때

enableImplicitConversion: false 인 경우

값이 "aaaa" 일 때

case2: isOptional이 아니어도, 조건결과가 false이면 error가 안나나?

즉, validateIf 조건값에 따라서 해당 속성자체를 보내지 않아도 되나? 된다

{
	"name":"another name",
  "test": 1,
	"brand": 7,
	"profile": {
		"photo": "ara.jpg",
		"skills": "steam"
	}
}//OK

주의해야할 점이 있다.

false면 아예 타입검사 자체를 하지 않는다. 즉 해당 속성에 명시한 타입과 완전히 다른 타입 값이 들어와도 검사를 안한다는 점에 주의하자.

( "property [속성명] should not exist") 가 일어나지 않고 통과한다.

{
	"name":"hello",
  "test":  {"ddd": "ddd"},
	"brand": 7,
	"profile": {
		"photo": "ara.jpg",
		"skills": "steam"
	}
}//OK


//내가 기대한 값
{
	"name":"hello",
  "eeeeeerrrrrrorrrrrr":  {"ddd": "ddd"},  // "property eeeeeerrrrrrorrrrrr should not exist"
	"brand": 7,
	"profile": {
		"photo": "ara.jpg",
		"skills": "steam"
	}
}//Error
profile
Sin prisa pero sin pausa (서두르지 말되, 멈추지도 말라)

0개의 댓글