@Bodyはclass-validator、class-transformerで検証する。

BodyはParam、Queryと違い、さまざまなデータフォーマットで送信される。ここではJSON形式で検証を行っている。

JSONはkey、valueで表す。valueのTypeは下記の通り。

value-Type 意味
string 文字列。日付もここに位置する
number 数値
array 配列。[]で囲まれている
boolean trueまたはfalse
null nullはnull
object JSONオブジェクト。{}で囲まれている

残念なことにDate型は存在しない。多くの場合はISO 8601規格のstringで表す。JavaScriptのDate.prototype.getTime()のようにミリ秒をnumberで渡す方法も考えられるが、そういうドキュメントは見たことない。

サンプル

@Queryのclass-validatorと異なる部分がある。Queryの場合はすべてのvalueは文字列であるため、文字列以外に変換する場合はtransform(変換)する必要がある。stringからnumberに変換する例などがわかりやすい。JSONの場合は、数値は数値として送られるため変換の必要がない。

Body(JSON)はネストして表示する場合が多い。これはQueryには存在しない表記になる。class-validatorのプロパティにはtypeまたはclassのみを指定する必要がある。多少面倒ではあるが、ネストするObjectプロパティに対しては別途、クラスを作成する必要がでてくる。

ネストする場合は@ValidateNested({ each: true })@Type(() => クラス名)が必要となる。

import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
import { Type } from 'class-transformer';
import { IsEnum, IsISO8601, IsNotEmpty, IsOptional, Max, MaxLength, MinLength, ValidateIf, ValidateNested } from 'class-validator';
export enum EnumClass {
  AAA = 'AAA',
  BBB = 'BBB',
  CCC = 'CCC',
  DDD = 'DDD',
}
export class Nest1Sample {
  @ApiProperty()
  @MaxLength(10)
  key1: string;
  @ApiProperty()
  @MinLength(10)
  key2: string;
}
export class SampleBody {
  /**
   * stringの文字列
   */
  @ApiProperty()
  @IsNotEmpty()
  @MaxLength(10)
  key1: string;
  /**
   * stringの文字列の配列
   */
  @ApiProperty()
  @IsNotEmpty()
  @MaxLength(10, {
    each: true,
  })
  key2: string[];
  /**
   * number型
   */
  @ApiProperty()
  @IsNotEmpty()
  @Max(10)
  key3: number;
  /**
   * stringの文字列の配列
   */
  @ApiProperty()
  @IsNotEmpty()
  @Max(10, {
    each: true,
  })
  key4: number[];
  /**
   * ISO8601形式の日付
   */
  @ApiProperty({ example: '2022-08-23T14:47:32.899Z' })
  @IsNotEmpty()
  @IsISO8601()
  key5: string;
  @ApiPropertyOptional({ enum: Object.values(EnumClass) })
  @IsOptional()
  @IsEnum(EnumClass)
  key6?: EnumClass;
  @ApiPropertyOptional({ enum: Object.values(EnumClass) })
  @IsOptional()
  @IsEnum(EnumClass, { each: true })
  key7?: EnumClass[] = [];
  @ApiProperty()
  @IsNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => Nest1Sample)
  nestClass: Nest1Sample;
  @ApiProperty()
  @ValidateNested()
  @Type(() => Nest1Sample)
  @IsNotEmpty()
  nestClassArray: Nest1Sample[];
  @ApiPropertyOptional()
  @IsOptional()
  condition1?: string;
  @ApiPropertyOptional()
  @ValidateIf((object, value) => {
    if (object.condition1) return true;
    return false;
  })
  @IsNotEmpty()
  condition2?: string;
  @ApiProperty()
  keyBatPattern1: {
    // @ApiProperty()  これはできない。
    // @MaxLength(10)  これはできない。
    name: string;
    body: string;
    hoge: {
      twitterID: number;
    };
  };
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112

資料

デコレーターの種類は多い。細かな検証が必要な場合はかなり頑張らないといけない。

条件により、検証が必要か不要なのかを切り替えることができる。