49. Pipes Globales - A nivel de Aplicación

 

Pipes Globales en NestJS: Validación a Nivel de Aplicación

En NestJS, los Pipes son una herramienta poderosa para transformar y validar datos. En este post, exploraremos cómo implementar Pipes a nivel global en nuestra aplicación, lo que nos permite centralizar la validación y mantener un código más limpio y consistente.

Estructura del Proyecto

Antes de comenzar, veamos la estructura de nuestro proyecto:

Copy
Download
src/
│
├── cars/
│   ├── dto/
│   │   ├── create-car.dto.ts
│   │   └── update-car.dto.ts
│   ├── interfaces/
│   │   └── car.interface.ts
│   ├── cars.controller.ts
│   ├── cars.module.ts
│   ├── cars.service.ts
│   └── constants/
│       └── car.constants.ts
│
├── common/
│   ├── pipes/
│   │   └── validation.pipe.ts
│   └── filters/
│       └── http-exception.filter.ts
│
├── app.module.ts
├── app.controller.ts
├── app.service.ts
└── main.ts

Antes: Validación por Controlador

Inicialmente, teníamos que aplicar el ValidationPipe en cada método del controlador donde necesitábamos validación:

typescript
Copy
Download
import { Controller, Get, Param, Post, Body, Patch, Delete, ParseIntPipe, UsePipes, ValidationPipe } from '@nestjs/common';
import { CarsService } from './cars.service';
import { CreateCarDto } from './dto/create-car.dto';

@Controller('cars')
export class CarsController {
  constructor(private readonly carsService: CarsService) {}

  @Get()
  getAllCars() {
    return this.carsService.findAll();
  }

  @Get(':id')
  getCarById(@Param('id') id: string) {
    return this.carsService.findOneById(+id);
  }

  @Post()
  @UsePipes(ValidationPipe)
  createCar(@Body() createCarDto: CreateCarDto) {
    return createCarDto;
  }

  @Patch(':id')
  updateCar(
    @Param('id', ParseIntPipe) id: number,
    @Body() body: any
  ) {
    return body;
  }

  @Delete(':id')
  deleteCar(@Param('id', ParseIntPipe) id: number) {
    return {
      method: 'delete',
      id
    };
  }
}

Este enfoque funciona, pero requiere repetir el decorador @UsePipes(ValidationPipe) en cada método que necesite validación.

Implementando Pipes Globales

Para simplificar y hacer más eficiente nuestro código, podemos configurar el ValidationPipe a nivel global en el archivo main.ts:

typescript
Copy
Download
import { NestFactory } from '@nestjs/core';
import { ValidationPipe } from '@nestjs/common';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.useGlobalPipes(
    new ValidationPipe({
      whitelist: true,
      forbidNonWhitelisted: true,
    }),
  );

  await app.listen(3000);
}
bootstrap();

Después: Controlador Limpio

Con el Pipe global configurado, nuestro controlador queda más limpio y la validación se aplica automáticamente:

typescript
Copy
Download
import { Controller, Get, Param, Post, Body, Patch, Delete, ParseIntPipe } from '@nestjs/common';
import { CarsService } from './cars.service';
import { CreateCarDto } from './dto/create-car.dto';

@Controller('cars')
export class CarsController {
  constructor(private readonly carsService: CarsService) {}

  @Get()
  getAllCars() {
    return this.carsService.findAll();
  }

  @Get(':id')
  getCarById(@Param('id') id: string) {
    return this.carsService.findOneById(+id);
  }

  @Post()
  createCar(@Body() createCarDto: CreateCarDto) {
    return createCarDto;
  }

  @Patch(':id')
  updateCar(
    @Param('id', ParseIntPipe) id: number,
    @Body() body: any
  ) {
    return body;
  }

  @Delete(':id')
  deleteCar(@Param('id', ParseIntPipe) id: number) {
    return {
      method: 'delete',
      id
    };
  }
}

Beneficios de los Pipes Globales

  1. Código más limpio: Elimina la necesidad de decoradores repetitivos en cada método.

  2. Consistencia: Asegura que todas las rutas tengan la misma validación.

  3. Configuración centralizada: Cambios en la validación se aplican en un solo lugar.

Configuración Avanzada del ValidationPipe

El ValidationPipe ofrece varias opciones útiles:

  • whitelist: Remueve propiedades no declaradas en el DTO

  • forbidNonWhitelisted: Rechaza solicitudes con propiedades no declaradas

  • transform: Transforma automáticamente los tipos de datos

  • disableErrorMessages: Deshabilita mensajes de error detallados en producción

Conclusión

Implementar Pipes globales en NestJS es una práctica recomendada que mejora la mantenibilidad y consistencia de nuestro código. Al centralizar la validación, reducimos la duplicación y aseguramos que todas las rutas cumplan con los mismos estándares de validación.

¿Has implementado Pipes globales en tus proyectos NestJS? ¡Comparte tus experiencias en los comentarios

Comentarios

Entradas más populares de este blog

48. ValidationPipe - Class Validator y Class Transformer

32-Modulos