48. ValidationPipe - Class Validator y Class Transformer
Validación de Datos en NestJS con ValidationPipe, Class-Validator y Class-Transformer
Cuando desarrollamos APIs, una de las tareas más comunes -y a veces tediosas- es validar que los datos que recibimos en las peticiones cumplan con ciertos estándares. ¿No sería genial tener una forma sencilla y automatizada de hacer esto? En NestJS, podemos lograrlo con el ValidationPipe junto con las librerías class-validator y class-transformer.
Antes: Validación Manual
Originalmente, nuestro controlador de autos (cars.controller.ts) aceptaba cualquier dato sin validación:
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
};
}
}Y nuestro DTO (create-car.dto.ts) era simplemente una clase sin validaciones:
export class CreateCarDto {
readonly Brand: string;
readonly model: string;
}Configurando las Validaciones
Para implementar validaciones automáticas, primero instalamos las dependencias necesarias:
yarn add class-validator class-transformerDespués: Validación Automática
Ahora, podemos decorar nuestro DTO con validadores:
import { IsString } from 'class-validator';
export class CreateCarDto {
@IsString({ message: 'The Brand must be a cool string' })
readonly Brand: string;
@IsString()
readonly model: string;
}Y aplicamos el ValidationPipe en nuestro controlador:
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
};
}
}Beneficios de este Enfoque
Validación automática: NestJS validará automáticamente que los datos cumplan con las reglas definidas.
Mensajes personalizados: Podemos definir mensajes de error específicos para cada validación.
Código más limpio: Elimina la necesidad de escribir manualmente validaciones repetitivas.
Tipado seguro: Mantenemos el tipado TypeScript en todo nuestro flujo de datos.
Decoradores Comunes de Class-Validator
Algunos de los decoradores más útiles incluyen:
@IsOptional()- El campo es opcional@IsPositive()- Debe ser un número positivo@IsString()- Debe ser una cadena de texto@IsEmail()- Debe ser un email válido@IsUrl()- Debe ser una URL válida@IsArray()- Debe ser un arreglo@IsDate()- Debe ser una fecha válida@IsBoolean()- Debe ser un valor booleano
Próximos Pasos
En una próxima publicación, veremos cómo configurar el ValidationPipe a nivel global para aplicarlo a todos los controladores automáticamente, evitando tener que decorar cada método individualmente.
¿Qué opinas de este enfoque para la validación de datos? ¿Lo has implementado en tus proyectos? ¡Déjame saber en los comentarios
Comentarios
Publicar un comentario