Kurs NestJS · Moduł 10: Walidacja danych
Zaawansowane dekoratory walidacji
W tej lekcji6
Podstawowi strażnicy bramy znasz już całkiem nieźle. Teraz czas poznać elitarnych gwardzistów - zaawansowane dekoratory class-validator, które radzą sobie z bardziej skomplikowanymi sytuacjami.
@IsOptional() - strażnik wartości opcjonalnych
Nie każde pole musi być obowiązkowe. Dekorator @IsOptional() mówi: "Jeśli to pole istnieje, sprawdź je. Jeśli nie istnieje - przepuść":
1import { IsOptional, IsString, IsNumber } from 'class-validator';
2
3export class UpdateLegionaryDto {
4 @IsOptional()
5 @IsString()
6 nickname?: string; // Może nie mieć pseudonimu
7
8 @IsOptional()
9 @IsNumber()
10 bonusPay?: number; // Dodatkowy żołd jest opcjonalny
11}@IsEnum() - strażnik dozwolonych wartości
Gdy pole może przyjmować tylko określone wartości, używamy @IsEnum(). To jak lista dozwolonych rang w legionie:
1import { IsEnum } from 'class-validator';
2
3enum LegionaryRank {
4 MILES = 'miles',
5 OPTIO = 'optio',
6 CENTURIO = 'centurio',
7 LEGATUS = 'legatus',
8}
9
10export class CreateLegionaryDto {
11 @IsEnum(LegionaryRank)
12 rank: LegionaryRank;
13 // 'centurio', 'imperator'
14}@IsArray() i @ArrayMinSize() - strażnicy tablic
Gdy oczekujesz tablicy danych, potrzebujesz specjalnych strażników:
1import { IsArray, ArrayMinSize, IsString } from 'class-validator';
2
3export class CreateLegioDto {
4 @IsArray()
5 @ArrayMinSize(1)
6 @IsString({ each: true })
7 skills: string[];
8 // ["combat", "march"], [], "combat"
9}Zwróć uwagę na { each: true } - ten parametr mówi dekoratorowi @IsString(), żeby sprawdził każdy element tablicy, a nie samą tablicę.
@IsDateString() - strażnik dat
Weryfikuje, czy wartość jest poprawnym łańcuchem daty w formacie ISO 8601:
1import { IsDateString } from 'class-validator';
2
3export class CreateEventDto {
4 @IsDateString()
5 enlistmentDate: string;
6 // "2024-03-15T10:00:00Z", "wczoraj"
7}@Matches() - strażnik wzorców (regex)
Najuniwersalniejszy strażnik - sprawdza, czy wartość pasuje do wyrażenia regularnego:
1import { Matches, IsString } from 'class-validator';
2
3export class CreateLegionaryDto {
4 @IsString()
5 @Matches(/^LEG-[A-Z]{3}-\d{4}$/, {
6 message: 'Numer identyfikacyjny musi mieć format LEG-XXX-0000',
7 })
8 militaryId: string;
9 // "LEG-ROM-0042", "123ABC"
10}Pełny przykład - formularz rekrutacji do legionu
Połączmy wszystkie zaawansowane dekoratory w kompletnym DTO:
1import {
2 IsString,
3 IsNotEmpty,
4 IsEnum,
5 IsOptional,
6 IsArray,
7 ArrayMinSize,
8 IsDateString,
9 Matches,
10 IsNumber,
11 Min,
12 Max,
13 MinLength,
14} from 'class-validator';
15
16enum LegionaryRank {
17 MILES = 'miles',
18 OPTIO = 'optio',
19 CENTURIO = 'centurio',
20 LEGATUS = 'legatus',
21}
22
23export class RecruitLegionaryDto {
24 @IsString()
25 @IsNotEmpty()
26 @MinLength(2)
27 name: string;
28
29 @IsEnum(LegionaryRank)
30 rank: LegionaryRank;
31
32 @IsNumber()
33 @Min(16)
34 @Max(65)
35 age: number;
36
37 @IsDateString()
38 enlistmentDate: string;
39
40 @Matches(/^LEG-[A-Z]{3}-\d{4}$/)
41 militaryId: string;
42
43 @IsArray()
44 @ArrayMinSize(1)
45 @IsString({ each: true })
46 skills: string[];
47
48 @IsOptional()
49 @IsString()
50 nickname?: string;
51}Mając te dekoratory w swoim arsenale, możesz walidować praktycznie dowolne dane. Strażnicy bramy twojego API są teraz dobrze wyszkoleni!
Kod do tej lekcji: src/advanced-decorators.ts
1// Zaawansowane dekoratory walidacji
2import {
3 IsString,
4 IsNotEmpty,
5 IsEnum,
6 IsOptional,
7 IsArray,
8 ArrayMinSize,
9 IsDateString,
10 Matches,
11 IsNumber,
12 Min,
13} from 'class-validator';
14
15// Enumy rang legionistów
16enum LegionaryRank {
17 MILES = 'miles',
18 OPTIO = 'optio',
19 CENTURIO = 'centurio',
20 LEGATUS = 'legatus',
21}
22
23// TODO: Uzupełnij DTO zaawansowanymi dekoratorami
24export class RecruitLegionaryDto {
25 @IsString()
26 @IsNotEmpty()
27 name: string;
28
29 // TODO: Dodaj @IsEnum z LegionaryRank
30 rank: LegionaryRank;
31
32 @IsNumber()
33 @Min(16)
34 age: number;
35
36 // TODO: Dodaj @IsDateString()
37 enlistmentDate: string;
38
39 // TODO: Dodaj @Matches z regexem /^LEG-[A-Z]{3}-\d{4}$/
40 militaryId: string;
41
42 // TODO: Dodaj @IsArray, @ArrayMinSize(1), @IsString({ each: true })
43 skills: string[];
44
45 // TODO: Dodaj @IsOptional() i @IsString()
46 nickname?: string;
47}
48
49console.log('Zaawansowane dekoratory gotowe!');
50Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Co robi dekorator @IsOptional() w class-validator?
2. Do czego służy dekorator @IsEnum() w class-validator?
To 2 z 3 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Edytor kodu
Uzupełnij enum ProvinceType i dodaj dekoratory walidacji do CreateProvinceDto
- Układanie w pionie
Uporządkuj dekoratory od najmniej do najbardziej restrykcyjnego:
- Edytor kodu
Uzupełnij dekoratory @Matches i @IsDateString w CreateDocumentDto
- Klikanie w kolejności
Ułóż elementy dekoratora @Matches w prawidłowej kolejności: