nestjs dto validation guide

gosuยท2024๋…„ 3์›” 22์ผ
0
post-thumbnail

๐Ÿš€ nestjs dto validation guide

DTO: Data Transfer Object
ํด๋ผ์ด์–ธํŠธ ์ธก์—์„œ Request๋ฅผ ๋ฐ›์„ ๋•Œ 'ํƒ€์ž… ์ง€์ •'๋งŒ์œผ๋กœ validation ํ•  ์ˆ˜ ์—†๋‹ค,
๋”ฐ๋ผ์„œ ๊ธฐ๋ณธ validation ์‚ฌ์šฉ ๋ฐฉ๋ฒ•๊ณผ custom validation์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒ€์ฆํ•˜๋Š” ๊ฒƒ์— ๋Œ€ํ•ด ์ •๋ฆฌํ•˜๊ฒ ๋‹ค.

1. PickType ๐Ÿชต

entity์—์„œ ์ •์˜๋œ ์ œ์•ฝ ์กฐ๊ฑด์„ PickType ํ™œ์šฉํ•ด dto์—์„œ๋„ ํ™œ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

  • ๋‹ค์Œ๊ณผ ๊ฐ™์ด Mail ์—”ํ‹ฐํ‹ฐ์—์„œ ์ •์˜๋œ 'title'๊ณผ 'html' ํ•„๋“œ๋ฅผ ๊ฐ€์ ธ์™€ ๋™์ผํ•œ ์ œ์•ฝ์กฐ๊ฑด์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.
export class CreateMailDto extends PickType(Mail, [
  'title',
  'html',
]) {
  @IsArray()
  @Validate(CheckEmailList)
  userList: string[];
}

2. class-validator decorator ๐Ÿ—๏ธ

nestjs ๊ณต์‹ ๋ฌธ์„œ์—์„œ ํ™•์ธํ•ด๋ณด๋ฉด class-validator ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ validation์„ ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜๊ณ  ์žˆ๋‹ค

  • https://docs.nestjs.com/techniques/validation
  • ์˜ˆ์‹œ์—์„œ @IsEmail(), @IsNotEmpty() ๋“ฑ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” validation์„ ์ง„ํ–‰ํ•œ๋‹ค.
import { IsEmail, IsNotEmpty } from 'class-validator';

export class CreateUserDto {
  @IsEmail()
  email: string;

  @IsNotEmpty()
  password: string;
}

๊ฐ€์žฅ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š” validator decorator

๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์„ค๋ช…
@IsString()ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’์ด ๋ฌธ์ž์—ด์ธ์ง€ ๊ฒ€์ฆ
@IsNotEmpty()ํ•„๋“œ๊ฐ€ ๋น„์–ด์žˆ์ง€ ์•Š์€์ง€ ๊ฒ€์ฆ. ๋ฌธ์ž์—ด, ๋ฐฐ์—ด ๋“ฑ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ณต๋ฐฑ ๋ฌธ์ž์—ด์ด๋‚˜ ๋นˆ ๋ฐฐ์—ด๋„ ์œ ํšจํ•˜์ง€ ์•Š์€ ๊ฐ’์œผ๋กœ ๊ฐ„์ฃผ
@IsEmail()ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’์ด ์œ ํšจํ•œ ์ด๋ฉ”์ผ ํ˜•์‹์ธ์ง€ ๊ฒ€์ฆ
@IsOptional()ํ•„๋“œ ๊ฐ’์ด ์ œ๊ณต๋˜์ง€ ์•Š๊ฑฐ๋‚˜ undefined์ผ ๊ฒฝ์šฐ์— ๊ฒ€์ฆ์„ ๊ฑด๋„ˆ๋œ€
@MinLength() / @MaxLength()๋ฌธ์ž์—ด์˜ ์ตœ์†Œ ๊ธธ์ด์™€ ์ตœ๋Œ€ ๊ธธ์ด๋ฅผ ๊ฒ€์ฆ
@IsInt() / @IsNumber()ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’์ด ์ •์ˆ˜ ๋˜๋Š” ์ˆซ์ž์ธ์ง€ ๊ฒ€์ฆ
@IsBoolean()ํ•„๋“œ ๊ฐ’์ด ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์ธ์ง€ ๊ฒ€์ฆ
@IsArray()ํ•ด๋‹น ํ•„๋“œ์˜ ๊ฐ’์ด ๋ฐฐ์—ด์ธ์ง€ ๊ฒ€์ฆ
@ArrayNotEmpty()๋ฐฐ์—ด์ด ๋น„์–ด์žˆ์ง€ ์•Š์€์ง€ ๊ฒ€์ฆ
@ValidateNested()๊ฐ์ฒด ๋ฐฐ์—ด์—์„œ ๊ฐ ๊ฐ์ฒด๋ฅผ ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. @Type() ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜์–ด, ๋ฐฐ์—ด ๋‚ด ๊ฐ์ฒด์˜ ํด๋ž˜์Šค ํƒ€์ž…์„ ๋ช…์‹œํ•˜๊ณ  ๊ทธ ๊ฐ์ฒด๋“ค์ด ์œ ํšจํ•œ์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค.

/node_modules/class-validator/types/decorator

  • ๋‹ค์Œ ํด๋”์—์„œ ์ด๋ฏธ ์ž์ฒด์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” validation decorator๋ฅผ ํ™•์ธํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค.

3. custom-validation decorator โœจ

์œ„์˜ ๊ธฐ๋ณธ ์ œ๊ณต class-validator decorator๋งŒ์œผ๋กœ๋Š” ๋ชจ๋“  ๊ฒ€์ฆ์„ ๋‹ค ํ•˜๊ธฐ ์–ด๋ ค์šด ๋ถ€๋ถ„์ด ์žˆ๋‹ค.
service ๋‹จ์—์„œ dto์˜ ๊ฐ’์„ ๊ฒ€์ฆํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๊ฒ ์ง€๋งŒ, dto ์ž์ฒด์˜ ๋ฌธ์ œ์ด๋ฏ€๋กœ ๋‚˜๋Š” dto ๋‹จ์—์„œ ๊ฒ€์ฆ์„ ๋งˆ์น˜๋Š” ๊ฒƒ์„ ์„ ํ˜ธํ•œ๋‹ค.

  • @ValidatorConstraint ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ custom validator class๋ฅผ ๋“ฑ๋กํ•  ์ˆ˜ ์žˆ๋‹ค.
  • @ValidatorConstraint ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋ฐ˜๋“œ์‹œ ValidatorConstraintInterface๋ฅผ ๋ฐ›์•„ ๊ตฌํ˜„์„ ์ง„ํ–‰ํ•ด์•ผํ•˜๊ณ , return์œผ๋กœ ๋ถˆ๋ฆฌ์–ธ ํƒ€์ž…์„ ๋ฐ›์•„ ๊ฒ€์ฆ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.
@ValidatorConstraint({ name: 'IsEvenNumber' })
export class IsEvenNumber implements ValidatorConstraintInterface {
  validate(value: number): boolean {
    if (value {
      return value % 2 === 0
    }
    return false
  }
}

export class SpecificNumber {
  // ์ง์ˆ˜์ธ์ง€ ์ฒดํฌ
  @Validate(IsEvenNumber, { message: 'No Even Number' })
  specificNumber: number
}
profile
๊ฐœ๋ฐœ์ž ๋ธ”๋กœ๊ทธ ^0^

0๊ฐœ์˜ ๋Œ“๊ธ€