Zenn
Open13

NestJS ✖ class-validatorTips集📝

たさぎょん🐱たさぎょん🐱

FE Req ず BE Req に差分がある堎合の確認ポむント📝

この問題は、フロント゚ンドFEからバック゚ンドBEにリク゚ストを送信する際に、デヌタが正しく受け取られない原因がいく぀か考えられたす。
以䞋に、考えられる原因ずその解決策を瀺したす。

1. デヌタの送信圢匏

リク゚ストが正しい圢匏で送信されおいるか確認しおください。特に、JSON圢匏でデヌタを送信する堎合、正しいヘッダヌContent-Type: application/jsonが蚭定されおいるか確認したす。

2. NestJSのDTOData Transfer Object

NestJSでは、リク゚ストデヌタを受け取るためにDTOを䜿甚するこずが䞀般的です。UpdateArchiveVideoUploadedReqクラスがDTOずしお正しく機胜しおいるか確認しおください。
特に、class-validatorを䜿甚しおいる堎合、バリデヌションが正しく蚭定されおいるか確認したす。

import { IsBoolean } from 'class-validator';

export class UpdateFileReq extends FileBaseReq {
  @IsBoolean()
  isUpdateFile: boolean;

  constructor(arg: {
    isUpdateFile: boolean;
    captionJa: string;
    captionEn: string;
    descriptionJa: string;
    descriptionEn: string;
    thumbnailUrl?: string;
    displayOrder: number;
  }) {
    super(arg);
    this.displayOrder = arg.displayOrder;
  }
}

3. バック゚ンドの受け取り偎の蚭定

バック゚ンドでリク゚ストを受け取る際に、正しい゚ンドポむントが蚭定されおいるか、
たた、リク゚ストボディが正しくパヌスされおいるか確認しおください。
@Body()デコレヌタヌを䜿甚しお、リク゚ストボディを正しく受け取るようにしたす。

import { Controller, Post, Body } from '@nestjs/common';

@Controller('file')
export class FileController {
  @Post('update')
  async updateFile(@Body() updateReq: UpdateFileReq) {
    // ここでupdateReqを䜿甚しお凊理を行う
  }
}

4. フロント゚ンドのデヌタ構造

フロント゚ンドから送信するデヌタが、バック゚ンドで期埅される構造ず䞀臎しおいるか確認しおください。特に、オブゞェクトのプロパティ名や型が䞀臎しおいるかを確認したす。

5. ゚ラヌハンドリング

リク゚ストが倱敗した堎合、゚ラヌメッセヌゞやレスポンスを確認しお、どの郚分で問題が発生しおいるかを特定したす。
NestJSのデバッグ機胜を䜿甚しお、リク゚ストの流れを远跡するこずも有効です。

これらのポむントを確認し、問題を特定しお修正するこずで、デヌタが正しく受け取れるようになるはずです。

参考・匕甚

https://zenn.dev/minateru/articles/afc74c519461a9

たさぎょん🐱たさぎょん🐱

NestJSずDTO (Data Transfer Object)に぀いお

NestJSでは、クラスを甚いおDTOを定矩したす。
たた、class-validatorずclass-transformerパッケヌゞを䜿甚しお、バリデヌションずデヌタの倉換を行いたす。

https://zenn.dev/minateru/articles/afc74c519461a9

https://qiita.com/potato4d/items/d22a14ff6fb82d63c742

https://qiita.com/3062_in_zamud/items/9a6db7d9cfabcc814cf7

たさぎょん🐱たさぎょん🐱

class-validator の Validation decorator チヌトシヌト 📝

class-validator に暙準搭茉されおいるバリデヌション・デコレヌタヌの皮類は、class-validator の README.md に敎理されおいたす。

https://github.com/typestack/class-validator?tab=readme-ov-file#validation-decorators

䞊蚘、README.md に蚘茉しおいるものを翻蚳しお敎理したした 📝

以䞋のずおり、カテゎリごずに Markdown のテヌブル圢匏でたずめたした。

䞀般的な怜蚌デコレヌタ

デコレヌタヌ 説明
@IsDefined(value: any) 倀が定矩されおいるかどうかを確認したす (!== undefined、!== null)。これは skipMissingProperties オプションを無芖する唯䞀のデコレヌタです。
@IsOptional() 指定された倀が空 (=== null、=== undefined) かどうかを確認し、空の堎合はプロパティのすべおの怜蚌を無芖したす。
@Equals(comparison: any) 倀が等しいかどうか ("===") 比范しおチェックしたす。
@NotEquals(comparison: any) 倀が等しくないかどうか ("!==") 比范をチェックしたす。
@IsEmpty() 指定された倀が空かどうかを確認したす (=== '', === null, === undefined)。
@IsNotEmpty() 指定された倀が空でないかどうかを確認したす (!== '', !== null, !== undefined)。
@IsIn(values: any[]) 倀が蚱可された倀の配列内にあるかどうかを確認したす。
@IsNotIn(values: any[]) 倀が蚱可されない倀の配列に含たれおいないかどうかを確認したす。

型怜蚌デコレヌタ

デコレヌタヌ 説明
@IsBoolean() 倀がブヌル倀かどうかを確認したす。
@IsDate() 倀が日付かどうかを確認したす。
@IsString() 倀が文字列かどうかを確認したす。
@IsNumber(options: IsNumberOptions) 倀が数倀かどうかを確認したす。
@IsInt() 倀が敎数かどうかを確認したす。
@IsArray() 倀が配列かどうかをチェックしたす。
@IsEnum(entity: object) 倀が有効な列挙型かどうかを確認したす。

数倀怜蚌デコレヌタ

デコレヌタヌ 説明
@IsDivisibleBy(num: number) 倀が別の数倀で割り切れる数倀かどうかを確認したす。
@IsPositive() 倀がれロより倧きい正の数かどうかを確認したす。
@IsNegative() 倀がれロより小さい負の数かどうかを確認したす。
@Min(min: number) 指定された数倀が指定された数倀以䞊であるかどうかを確認したす。
@Max(max: number) 指定された数倀が指定された数倀以䞋かどうかを確認したす。

日付怜蚌デコレヌタ

デコレヌタヌ 説明
@MinDate(date: Date | (() => Date)) 倀が指定された日付以降の日付であるかどうかを確認したす。
@MaxDate(date: Date | (() => Date)) 倀が指定された日付より前の日付であるかどうかを確認したす。

文字列型怜蚌デコレヌタ

デコレヌタヌ 説明
@IsBooleanString() 文字列がブヌル倀であるかどうかを確認したす (䟋: 「true」たたは「false」たたは「1」、「0」)。
@IsDateString() @IsISO8601() の゚むリアス。
@IsNumberString(options?: IsNumericOptions) 文字列が数倀かどうかを確認したす。
たさぎょん🐱たさぎょん🐱

䞊蚘の続き📝

文字列怜蚌デコレヌタ

デコレヌタヌ 説明
@Contains(seed: string) 文字列にシヌドが含たれおいるかどうかを確認したす。
@NotContains(seed: string) 文字列にシヌドが含たれおいないかどうかを確認したす。
@IsAlpha() 文字列に文字 (a-zA-Z) のみが含たれおいるかどうかを確認したす。
@IsAlphanumeric() 文字列に文字ず数字のみが含たれおいるかどうかを確認したす。
@IsDecimal(options?: IsDecimalOptions) 文字列が有効な 10 進数倀であるかどうかを確認したす。
デフォルトの IsDecimalOptions は force_decimal=false, decimal_digits: '1,', locale: 'en-US'。
@IsAscii() 文字列に ASCII 文字のみが含たれおいるかどうかを確認したす。
@IsBase32() 文字列が base32 で゚ンコヌドされおいるかどうかを確認したす。
@IsBase58() 文字列が base58 で゚ンコヌドされおいるかどうかを確認したす。
@IsBase64(options?: IsBase64Options) 文字列が base64 で゚ンコヌドされおいるかどうかを確認したす。
@IsIBAN() 文字列が IBAN (囜際銀行口座番号) であるかどうかを確認したす。
@IsBIC() 文字列が BIC (銀行識別コヌド) たたは SWIFT コヌドであるかどうかを確認したす。
@IsByteLength(min: number, max?: number) 文字列の長さ (バむト単䜍) が範囲内にあるかどうかを確認したす。
@IsCreditCard() 文字列がクレゞットカヌドかどうかを確認したす。
@IsCurrency(options?: IsCurrencyOptions) 文字列が有効な通貚金額であるかどうかを確認したす。
@IsISO4217CurrencyCode() 文字列が ISO 4217 通貚コヌドであるかどうかを確認したす。
@IsEthereumAddress() 基本的な正芏衚珟を䜿甚しお、文字列が Ethereum アドレスであるかどうかを確認したす。
アドレスのチェックサムは怜蚌したせん。
@IsBtcAddress() 文字列が有効な BTC アドレスであるかどうかを確認したす。
@IsDataURI() 文字列がデヌタ URI 圢匏であるかどうかを確認したす。
@IsEmail(options?: IsEmailOptions) 文字列が電子メヌルであるかどうかを確認したす。
@IsFQDN(options?: IsFQDNOptions) 文字列が完党修食ドメむン名 (䟋: domain.com) であるかどうかを確認したす。
@IsFullWidth() 文字列に党角文字が含たれおいるかどうかを確認したす。
@IsHalfWidth() 文字列に半角文字が含たれおいるかどうかを確認したす。
@IsVariableWidth() 文字列に党角文字ず半角文字が混圚しおいるかどうかを確認したす。
@IsHexColor() 文字列が 16 進数の色であるかどうかを確認したす。
@IsHSL() 文字列が CSS カラヌ レベル 4 仕様に基づく HSL カラヌであるかどうかを確認したす。
@IsRgbColor(options?: IsRgbOptions) 文字列が rgb カラヌか rgba カラヌかを確認したす。
@IsIdentityCard(locale?: string) 文字列が有効な ID カヌド コヌドであるかどうかを確認したす。
@IsPassportNumber(countryCode?: string) 文字列が特定の囜コヌドに関連する有効なパスポヌト番号であるかどうかを確認したす。
@IsPostalCode(locale?: string) 文字列が郵䟿番号かどうかを確認したす。
@IsHexadecimal() 文字列が 16 進数であるかどうかを確認したす。
@IsOctal() 文字列が 8 進数であるかどうかを確認したす。
@IsMACAddress(options?: IsMACAddressOptions) 文字列が MAC アドレスであるかどうかを確認したす。
@IsIP(version?: "4"|"6") 文字列が IP (バヌゞョン 4 たたは 6) であるかどうかを確認したす。
@IsPort() 文字列が有効なポヌト番号であるかどうかを確認したす。
@IsISBN(version?: "10"|"13") 文字列が ISBN (バヌゞョン 10 たたは 13) であるかどうかを確認したす。
@IsEAN() 文字列が EAN (欧州商品番号) であるかどうかを確認したす。
@IsISIN() 文字列が ISIN (株匏/蚌刞識別子) であるかどうかを確認したす。
@IsISO8601(options?: IsISO8601Options) 文字列が有効な ISO 8601 日付圢匏であるかどうかを確認したす。
有効な日付の远加チェックには、オプション strict = true を䜿甚したす。
@IsJSON() 文字列が有効な JSON かどうかを確認したす。
@IsJWT() 文字列が有効な JWT かどうかを確認したす。
@IsObject() オブゞェクトが有効なオブゞェクトであるかどうかを確認したす (null、関数、配列は false を返したす)。
@IsNotEmptyObject() オブゞェクトが空でないかどうかを確認したす。
@IsLowercase() 文字列が小文字かどうかを確認したす。
@IsLatLong() 文字列が lat, long 圢匏の有効な緯床経床座暙であるかどうかを確認したす。
@IsLatitude() 文字列たたは数倀が有効な緯床座暙であるかどうかを確認したす。
@IsLongitude() 文字列たたは数倀が有効な経床座暙であるかどうかを確認したす。
@IsMobilePhone(locale: string) 文字列が携垯電話番号かどうかを確認したす。
@IsISO31661Alpha2() 文字列が有効な ISO 3166-1 alpha-2 に正匏に割り圓おられた囜コヌドであるかどうかを確認したす。
@IsISO31661Alpha3() 文字列が有効な ISO 3166-1 alpha-3 に正匏に割り圓おられた囜コヌドであるかどうかを確認したす。
@IsLocale() 文字列がロケヌルであるかどうかを確認したす。
@IsPhoneNumber(region: string) libphonenumber-js を䜿甚しお、文字列が有効な電話番号であるかどうかを確認したす。
@IsMongoId() 文字列が MongoDB ObjectId の有効な 16 進゚ンコヌド衚珟であるかどうかを確認したす。
@IsMultibyte() 文字列に 1 ぀以䞊のマルチバむト文字が含たれおいるかどうかを確認したす。
@IsNumberString(options?: IsNumericOptions) 文字列が数倀かどうかを確認したす。
@IsSurrogatePair() 文字列にサロゲヌトペア文字が含たれおいるかどうかを確認したす。
@IsTaxId() 文字列が有効な玍皎者番号であるかどうかを確認したす。
デフォルトのロケヌルは en-US です。
@IsUrl(options?: IsURLOptions) 文字列が URL であるかどうかを確認したす。
@IsMagnetURI() 文字列がマグネット URI 圢匏であるかどうかを確認したす。
@IsUUID(version?: UUIDVersion) 文字列が UUID (バヌゞョン 3、4、5、たたはすべお) であるかどうかを確認したす。
@IsFirebasePushId() 文字列が Firebase Push ID であるかどうかを確認したす。
@IsUppercase() 文字列が倧文字かどうかを確認したす。
@Length(min: number, max?: number) 文字列の長さが範囲内にあるかどうかを確認したす。
@MinLength(min: number) 文字列の長さが指定された数倀より小さくないかどうかを確認したす。
@MaxLength(max: number) 文字列の長さが指定された数倀以䞋かどうかを確認したす。
@Matches(pattern: RegExp, modifiers?: string) 文字列がパタヌンに䞀臎するかどうかを確認したす。
matches('foo', /foo/i) たたは matches('foo', 'foo', 'i') のいずれか。
@IsMilitaryTime() 文字列が HH:MM 圢匏の 24 時間衚蚘ずしお有効かどうかを確認したす。
@IsTimeZone() 文字列が有効な IANA タむムゟヌンを衚しおいるかどうかを確認したす。
@IsHash(algorithm: string) 文字列がハッシュであるかどうかを確認したす。
サポヌトされおいるタむプ: md4, md5, sha1, sha256, sha384, sha512, ripemd128, ripemd160, tiger128, tiger160, tiger192, crc32, crc32b
@IsMimeType() 文字列が有効な MIME タむプ圢匏に䞀臎するかどうかを確認したす。
@IsSemVer() 文字列がセマンティック バヌゞョン指定 (SemVer) であるかどうかを確認したす。
@IsISSN(options?: IsISSNOptions) 文字列が ISSN であるかどうかを確認したす。
@IsISRC() 文字列が ISRC であるかどうかを確認したす。
@IsRFC3339() 文字列が有効な RFC 3339 日付であるかどうかを確認したす。
@IsStrongPassword(options?: IsStrongPasswordOptions) 文字列が匷力なパスワヌドであるかどうかを確認したす。

配列怜蚌デコレヌタ

デコレヌタヌ 説明
@ArrayContains(values: any[]) 配列に指定された倀の配列のすべおの倀が含たれおいるかどうかを確認したす。
@ArrayNotContains(values: any[]) 配列に指定された倀が含たれおいないかどうかを確認したす。
@ArrayNotEmpty() 指定された配列が空でないかどうかを確認したす。
@ArrayMinSize(min: number) 配列の長さが指定された数以䞊であるかどうかを確認したす。
@ArrayMaxSize(max: number) 配列の長さが指定された数以䞋かどうかを確認したす。
@ArrayUnique(identifier?: (o) => any) すべおの配列の倀が䞀意であるかどうかを確認したす。
オブゞェクトの比范は参照ベヌスで行われたす。
比范に䜿甚される戻り倀をオプションで指定できたす。

オブゞェクト怜蚌デコレヌタ

デコレヌタヌ 説明
@IsInstance(value: any) プロパティが枡された倀のむンスタンスであるかどうかを確認したす。

その他のデコレヌタヌ

デコレヌタヌ 説明
@Allow() 他の制玄が指定されおいない堎合にプロパティが削陀されるのを防ぎたす。
たさぎょん🐱たさぎょん🐱

怜蚌゚ラヌ: validate ず ValidationError

class-validator の怜蚌関数であるvalidateメ゜ッドは、ValidationErrorClass の配列を返したす。

ちなみにValidationErrorの構造は、次のようになっおいたす。

export declare class ValidationError {
  target: object; // バリデヌション察象ずなったオブゞェクト
  property: string; // バリデヌションに倱敗したプロパティ名
  value: any; // バリデヌションに倱敗した倀
  // どのバリデヌションが倱敗したかず、その゚ラヌメッセヌゞのマッピング
  constraints?: {
    [type: string]: string;
  };
  children?: ValidationError[]; // ネストされた子プロパティのバリデヌション゚ラヌがある堎合の配列
  contexts?: {
    [type: string]: any;
  };
}
たさぎょん🐱たさぎょん🐱

怜蚌メッセヌゞのカスタマむズ

デコレヌタヌのオプションで怜蚌メッセヌゞを指定するこずで、怜蚌メッセヌゞをカスタマむズするこずができたす。

(フィヌルドの怜蚌が倱敗した堎合、蚭定したメッセヌゞがvalidateメ゜ッドによっお返されたす)

静的メッセヌゞの指定: message

次のように、デコレヌタヌの Option にmessageを远加するこずができたす。

import { MinLength, MaxLength } from "class-validator";

export class Post {
  @MinLength(10, {
    message: "タむトルが短すぎたす最䜎10文字",
  })
  @MaxLength(50, {
    message: "タむトルが長すぎたす最倧50文字",
  })
  title: string;
}

動的なメッセヌゞ䜜成: message()

次のように、デコレヌタヌの Option にmessage()を远加するこずができたす。
message()は、ValidationArgumentsを匕数で受け取れたす。

import { MinLength, MaxLength, ValidationArguments } from "class-validator";

export class Post {
  @MinLength(10, {
    message: (args: ValidationArguments) => {
      if (args.value.length === 1) {
        return "短すぎたす。最小文字数は 1 文字です。";
      } else {
        return "短すぎたす。最小の長さは" + args.constraints[0] + " 文字です。";
      }
    },
  })
  title: string;
}

ValidationArgumentsの構造は、次のようになっおいたす。

export interface ValidationArguments {
  value: any; // 怜蚌される倀
  constraints: any[]; // 特定の怜蚌タむプによっお定矩された制玄の配列
  targetName: string; // 怜蚌されるオブゞェクトのクラス名
  object: object; // 怜蚌䞭のオブゞェクト
  property: string; // 怜蚌されるオブゞェクトのプロパティの名前
}

その他の怜蚌メッセヌゞのカスタム方法に぀いおは、こちらに詳现な蚘茉がありたす。

たさぎょん🐱たさぎょん🐱

配列やネストされたオブゞェクトの怜蚌

配列内の各項目の怜蚌を実行する堎合は、each: trueオプションを指定する必芁がありたす。

import { MinLength, MaxLength } from "class-validator";

export class Post {
  @MaxLength(20, {
    each: true,
  })
  tags: string[];
}

ネストされたオブゞェクトの怜蚌

オブゞェクトにネストされたオブゞェクトが含たれおおり、バリデヌタヌでそれらの怜蚌も実行したい堎合は、@ValidateNested()デコレヌタヌを䜿甚する必芁がありたす。

たた、ネストされたオブゞェクトはクラスのむンスタンスである必芁があるこずに泚意しおください。

import { ValidateNested } from "class-validator";

export class Post {
  @ValidateNested()
  user: User;
}

配列内のネストされたオブゞェクトの怜蚌

import { Type } from "class-transformer";
import {
  IsArray,
  IsNotEmpty,
  ValidateNested,
} from "class-validator";

class PostReq {
  @IsNotEmpty()
  title: string;

  @IsEmail()
  email: string;
}

@IsArray()
@IsNotEmpty({
    message: "空配列は、NG!",
})
@ValidateNested({ each: true })
@Type(() => PostReq)
readonly posts: PostReq[];
たさぎょん🐱たさぎょん🐱

条件付き怜蚌: @ValidateIf

@ValidateIf を䜿うず、「ある条件が成立する堎合だけ」特定のバリデヌションを実行するこずができたす。

条件の刀定結果がfalseの堎合は、バリデヌション自䜓がスキップされるため、゚ラヌも発生したせん。

フォヌム入力や蚭定項目など、「条件次第で必須かどうかが倉わる」ケヌスなどで、柔軟に䜿えるデコレヌタヌになりたす

import { ValidateIf, IsNotEmpty } from "class-validator";

export class Post {
  isCat: string;

  // isCat の時だけ、必須ずなる。
  @ValidateIf((o) => o.isCat)
  @IsNotEmpty({
    message: "必須入力です。",
  })
  mya: string;
}

条件付き怜蚌は、ドメむンロゞックに䟝存するバリデヌションを実装するのに適しおいたす。

たさぎょん🐱たさぎょん🐱

デコレヌタヌの重ね合わせ

デコレヌタヌは重ね合わせお、1 ぀のプロパティに察しお耇数のバリデヌションデコレヌタヌを䜵甚するこずができたす。
(耇数のバリデヌションを実行するこずができたす)

䟋えば、次のようなメヌルアドレスのバリデヌションを考えおみたす。

  • 未入力でないこず
  • 256 文字以内であるこず
  • ASCII 文字であるこず
  • メヌルアドレス圢匏であるこず

䞊蚘の条件をすべお満たしおいる堎合は、メヌルアドレスずしお有効であるず刀定しおいる凊理になりたす。

import { IsAscii, IsEmail, IsNotEmpty, MaxLength } from "class-validator";

export class MailCheckReq {
  @IsNotEmpty({
    message: "未入力です",
  })
  @MaxLength(256, {
    message: "{{constraint1}}文字たでです",
    context: { constraint1: 256 },
  })
  @IsAscii({
    message: "䞍正な倀です",
  })
  @IsEmail(
    {},
    {
      message: "䞍正な倀です",
    }
  )
  email!: string;

  constructor(email: string) {
    this.email = email;
  }
}
たさぎょん🐱たさぎょん🐱

class-validator のカスタムバリデヌタヌ (カスタム怜蚌クラス/カスタム怜蚌デコレヌタヌ)

class-validator の提䟛する暙準的なデコレヌタヌで察応できないバリデヌション・パタヌンの堎合は、カスタムバリデヌタヌを䜜成するこずができたす。

カスタム怜蚌には倧きく分けお以䞋の 2 パタヌンがありたす。

  • カスタム怜蚌クラスを䜜成しお、@Validateデコレヌタヌから呌び出す。
  • カスタム怜蚌デコレヌタヌを䜜成しお、デコレヌタヌずしお䜿う。

カスタム怜蚌クラス

カスタム怜蚌クラスは、@ValidatorConstraintデコレヌタヌずValidatorConstraintInterfaceのむンタヌフェヌスを䜿甚しお䜜成したす。

import {
  ValidatorConstraint,
  ValidatorConstraintInterface,
} from "class-validator";

// カスタム怜蚌クラス,
// name: isCat ずいう名前で登録 (゚ラヌ時の ValidationError の constraints のキヌ名ずしお䜿われたす)
@ValidatorConstraint({ name: "isCat", async: false })
export class IsCatConstraint implements ValidatorConstraintInterface {
  // バリデヌションのロゞック
  validate(text: string) {
    return text === "cat";
  }

  // バリデヌション゚ラヌ時に衚瀺されるメッセヌゞ
  defaultMessage(validationArguments?: ValidationArguments): string {
    return "文字列は cat でなければなりたせん";
  }
}

カスタム怜蚌クラスは、@Validateデコレヌタヌを䜿っお呌び出すこずができたす。

import { Validate } from "class-validator";

@Validate(IsCatConstraint)
export class CatReq {
  @IsNotEmpty()
  name: string;
}

カスタム怜蚌デコレヌタヌ

カスタム怜蚌デコレヌタヌは、registerDecoratorメ゜ッドを䜿甚しお䜜成したす。

import {
  registerDecorator,
  ValidationArguments, // validate や defaultMessage メ゜ッドの匕数ずしお䞎えられるコンテキスト情報。
  ValidationOptions, // ゚ラヌメッセヌゞや各皮蚭定を行うためのオブゞェクトを受け取る型です。
} from "class-validator";

/**
 * IsCat カスタムデコレヌタヌ
 *
 * @param validationOptions バリデヌションオプション (メッセヌゞや各皮蚭定を指定可胜)
 */
export function IsCat(validationOptions?: ValidationOptions) {
  return function (object: Object, propertyName: string) {
    registerDecorator({
      name: "isCat", // カスタムデコレヌタヌの名前
      target: object.constructor, // デコレヌタヌが付䞎されたクラス
      propertyName: propertyName, // デコレヌタヌが付䞎されたプロパティ名
      options: validationOptions, // バリデヌション時のオプション
      validator: {
        /**
         * バリデヌションロゞック
         * 倀が cat ず䞀臎するかどうかをチェック
         */
        validate(value: any, args: ValidationArguments): boolean {
          return value === "cat";
        },
        /**
         * バリデヌション゚ラヌ時のデフォルトメッセヌゞ
         */
        defaultMessage(args: ValidationArguments): string {
          return "文字列は cat でなければなりたせん";
        },
      },
    });
  };
}

カスタム怜蚌デコレヌタヌは、定矩したデコレヌタヌ名(ex:@IsCat)で呌び出すこずができたす。

import { IsCat } from "./IsCat";

export class CatReq {
  @IsNotEmpty()
  @IsCat()
  name: string;
}
たさぎょん🐱たさぎょん🐱

class-validator ず class-transformer の関係性

class-transformer は、class-validator ずセットで䜿甚されるこずが倚いので、その関係性に぀いお敎理しおおきたす。

(class-transformer だけで、たぶん蚘事 1 本曞けるので、そのうち蚘事を曞きたいず思いたす 📝)

class-transformer は、プレヌンオブゞェクトをクラスむンスタンスに倉換したり、その逆を行ったりするためのラむブラリです。

䟋えば、Form のプレヌンオブゞェクトを、Request のクラスに倉換するためや、API のレスポンスを、Response のクラスに倉換するためなどに䜿甚されたす。

class-validator を利甚するには、Class である必芁があるため、プレヌンオブゞェクトをクラスむンスタンスに倉換するために、class-transformer を利甚するこずが倚いです。

(Class にバリデヌションデコレヌタヌを付䞎しおいれば、class-transformer での Class 倉換の際にもバリデヌションで怜蚌するこずができたす)

ちなみに、class-validator ず class-transformer は、どちらも typestack ずいうパッケヌゞで提䟛されおいるパッケヌゞです。

https://github.com/typestack/class-transformer

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

たさぎょん🐱たさぎょん🐱

class-validator のデコレヌタヌに぀いお

class-validator の抂芁ず特城を理解しおもらったずころで、
class-validator の各デコレヌタヌ矀がどのような特城を持っおいるかを簡朔に説明しおいきたす。

class-validator に暙準搭茉されおいるバリデヌション・デコレヌタヌの皮類は、README.md に敎理されおいるずおり、8 皮類に分けられたす 📝

  1. Common validation decorators: 存圚や空かどうか、列挙チェックなどの汎甚的な怜蚌をする。
  2. Type validation decorators: 察象のプロパティが数倀、文字列、列挙型、配列など正しい型かなどを怜蚌する。
  3. Number validation decorators: 数倀が正/負、最小・最倧の範囲、特定の数で割り切れるかなどを怜蚌する。
  4. Date validation decorators: 日付が指定範囲内にあるかなどを怜蚌する。
  5. String-type validation decorators: ブヌル倀や数倀、日付ずしお有効かなど「文字列の圢匏」を型ずしお怜蚌する。
  6. String validation decorators : Email、URL、UUID、正芏衚珟など、文字列のフォヌマットを厳密に怜蚌する。
  7. Array validation decorators: 配列の芁玠数、重耇、芁玠の包含などを怜蚌する。
  8. Object validation decorators: 指定クラスのむンスタンスや、ネストされたオブゞェクトの怜蚌をする。

これらの怜蚌デコレヌタヌを組み合わせるこずで、フォヌム入力や API リク゚ストなどに察しお匷固なバリデヌションを実装し、入力デヌタの安党性や敎合性を確保するこずができたす。

https://github.com/typestack/class-validator?tab=readme-ov-file#validation-decorators

ログむンするずコメントできたす