Utilizziamo i cookie per migliorare la tua esperienza sul sito
CodeWorlds

ValidationPipe — Automatyczna stacja kontrolna

Poznałeś strażników (dekoratory class-validator) i wiesz, jak opisać reguły walidacji w DTO. Ale kto tak naprawdę uruchamia tych strażników? Odpowiedzią jest ValidationPipe — to jak główny oficer kontrolny stojący przy bramie i koordynujący pracę wszystkich strażników.

Czym jest ValidationPipe?

ValidationPipe to wbudowany pipe NestJS, który automatycznie:

  1. Przekształca przychodzące dane na instancję klasy DTO
  2. Uruchamia wszystkie dekoratory class-validator
  3. Zwraca błąd 400 Bad Request jeśli walidacja nie przejdzie

Konfiguracja globalna w main.ts

Najwygodniejszy sposób to włączenie ValidationPipe globalnie dla całej aplikacji:

1// main.ts - Brama Główna Imperium
2import { NestFactory } from '@nestjs/core';
3import { ValidationPipe } from '@nestjs/common';
4import { AppModule } from './app.module';
5
6async function bootstrap() {
7  const app = await NestFactory.create(AppModule);
8
9  // Ustawienie globalnej straży na bramie
10  app.useGlobalPipes(new ValidationPipe());
11
12  await app.listen(3000);
13}
14bootstrap();

Opcje konfiguracji ValidationPipe

ValidationPipe przyjmuje obiekt opcji, który pozwala dostosować zachowanie straży:

whitelist — przepuszczaj tylko znane pola

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3}));

Z opcją

whitelist: true
pipe automatycznie usunie wszystkie pola, które nie mają dekoratorów walidacji w DTO. To jak strażnik, który zabiera podejrzane przedmioty na bramie:

1// DTO pozwala tylko na 'name' i 'age'
2export class CreateLegionaryDto {
3  @IsString()
4  name: string;
5
6  @IsNumber()
7  age: number;
8}
9
10// Przychodzi request z dodatkowym polem:
11// { name: "Marcus", age: 25, isAdmin: true }
12
13// Z whitelist: true, pole 'isAdmin' zostaje usunięte
14// Kontroler dostaje: { name: "Marcus", age: 25 }

forbidNonWhitelisted — odrzuć żądania z nieznanymi polami

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3  forbidNonWhitelisted: true,
4}));

To jeszcze surowsza opcja — zamiast usuwać nieznane pola, serwer zwraca błąd. Strażnik nie zabiera przedmiotów, ale od razu odmawia wejścia:

1// { name: "Marcus", age: 25, isAdmin: true }
2// Odpowiedź: 400 Bad Request
3// "property isAdmin should not exist"

transform — automatyczna konwersja typów

1app.useGlobalPipes(new ValidationPipe({
2  transform: true,
3}));

Parametry URL zawsze przychodzą jako stringi. Z opcją

transform: true
pipe automatycznie konwertuje je na odpowiednie typy:

1@Get(':id')
2findOne(@Param('id') id: number) {
3  // Bez transform: id jest stringiem "42"
4  // Z transform: id jest liczbą 42
5  console.log(typeof id); // "number"
6}

Użycie na poziomie route'a

Możesz też użyć ValidationPipe na konkretnym endpoincie zamiast globalnie:

1@Post()
2@UsePipes(new ValidationPipe({ whitelist: true }))
3createLegionary(@Body() dto: CreateLegionaryDto) {
4  return this.service.create(dto);
5}

Albo na konkretnym parametrze:

1@Post()
2createLegionary(
3  @Body(new ValidationPipe({ whitelist: true })) dto: CreateLegionaryDto,
4) {
5  return this.service.create(dto);
6}

Rekomendowana konfiguracja produkcyjna

Oto konfiguracja, którą stosuje większość projektów NestJS:

1app.useGlobalPipes(new ValidationPipe({
2  whitelist: true,
3  forbidNonWhitelisted: true,
4  transform: true,
5  transformOptions: {
6    enableImplicitConversion: true,
7  },
8}));

Ta konfiguracja zapewnia:

  • Usuwanie nieznanych pól (
    whitelist
    )
  • Odrzucanie żądań z nieznanymi polami (
    forbidNonWhitelisted
    )
  • Automatyczną konwersję typów (
    transform
    )
  • Niejawną konwersję na podstawie typów TypeScript (
    enableImplicitConversion
    )

ValidationPipe to fundament bezpieczeństwa twojego API. Bez niego dekoratory class-validator są jak strażnicy bez dowódcy — nie wiedzą kiedy działać!

Vai a CodeWorlds