Validación con Pipes

Intermedio
Nest
Nest
Actualizado: 15/06/2025

Pipes existentes en Nest y cómo usarlos

Los pipes en NestJS son clases que implementan la interfaz PipeTransform y se ejecutan antes de que los datos lleguen al controlador. Su función principal es transformar los datos de entrada o validar que cumplan con ciertos criterios antes de procesarlos.

NestJS incluye varios pipes integrados que cubren las necesidades más comunes de validación y transformación. Estos pipes se pueden aplicar a nivel de parámetro, método o controlador, proporcionando flexibilidad en su implementación.

Pipes de validación integrados

ValidationPipe es el pipe más utilizado para validar objetos complejos usando decoradores de class-validator. Este pipe transforma automáticamente los objetos planos en instancias de clase y aplica las reglas de validación definidas:

import { Body, Controller, Post, UsePipes, ValidationPipe } from '@nestjs/common';
import { IsEmail, IsNotEmpty, MinLength } from 'class-validator';

class CreateUserDto {
  @IsNotEmpty()
  name: string;

  @IsEmail()
  email: string;

  @MinLength(6)
  password: string;
}

@Controller('users')
export class UsersController {
  @Post()
  @UsePipes(new ValidationPipe())
  create(@Body() createUserDto: CreateUserDto) {
    return `Usuario creado: ${createUserDto.name}`;
  }
}

ParseIntPipe convierte strings en números enteros y valida que la conversión sea exitosa. Es especialmente útil para parámetros de ruta que deben ser numéricos:

import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';

@Controller('users')
export class UsersController {
  @Get(':id')
  findOne(@Param('id', ParseIntPipe) id: number) {
    return `Usuario con ID: ${id}`;
  }
}

ParseBoolPipe transforma strings como "true" o "false" en valores booleanos reales:

import { Controller, Get, Query, ParseBoolPipe } from '@nestjs/common';

@Controller('products')
export class ProductsController {
  @Get()
  findAll(@Query('active', ParseBoolPipe) active: boolean) {
    return `Productos activos: ${active}`;
  }
}

Pipes de transformación de datos

ParseArrayPipe convierte strings separados por comas en arrays y puede aplicar transformaciones adicionales a cada elemento:

import { Controller, Get, Query, ParseArrayPipe } from '@nestjs/common';

@Controller('products')
export class ProductsController {
  @Get()
  findByIds(
    @Query('ids', new ParseArrayPipe({ items: Number, separator: ',' }))
    ids: number[]
  ) {
    return `Buscando productos: ${ids.join(', ')}`;
  }
}

ParseUUIDPipe valida que un string tenga formato UUID válido y puede especificar la versión requerida:

import { Controller, Get, Param, ParseUUIDPipe } from '@nestjs/common';

@Controller('orders')
export class OrdersController {
  @Get(':id')
  findOne(@Param('id', new ParseUUIDPipe({ version: '4' })) id: string) {
    return `Pedido con UUID: ${id}`;
  }
}

ParseEnumPipe valida que un valor pertenezca a un enum específico:

import { Controller, Get, Query, ParseEnumPipe } from '@nestjs/common';

enum OrderStatus {
  PENDING = 'pending',
  COMPLETED = 'completed',
  CANCELLED = 'cancelled'
}

@Controller('orders')
export class OrdersController {
  @Get()
  findByStatus(
    @Query('status', new ParseEnumPipe(OrderStatus))
    status: OrderStatus
  ) {
    return `Pedidos con estado: ${status}`;
  }
}

Aplicación de pipes a diferentes niveles

Los pipes se pueden aplicar de múltiples formas según el alcance deseado. A nivel de parámetro, el pipe solo afecta a ese parámetro específico:

@Get(':id')
findOne(@Param('id', ParseIntPipe) id: number) {
  return `Usuario: ${id}`;
}

A nivel de método, el pipe se aplica a todos los parámetros del método:

@Get(':id')
@UsePipes(ValidationPipe)
findOne(@Param('id') id: string, @Body() updateDto: UpdateUserDto) {
  return 'Método con pipe aplicado';
}

A nivel de controlador, el pipe afecta a todos los métodos del controlador:

@Controller('users')
@UsePipes(new ValidationPipe({ whitelist: true }))
export class UsersController {
  // Todos los métodos heredan el ValidationPipe
}

Configuración avanzada de pipes

Los pipes integrados aceptan opciones de configuración que modifican su comportamiento. El ValidationPipe, por ejemplo, puede configurarse para eliminar propiedades no definidas en el DTO:

@Post()
@UsePipes(new ValidationPipe({
  whitelist: true,           // Elimina propiedades no definidas en el DTO
  forbidNonWhitelisted: true, // Lanza error si hay propiedades extra
  transform: true            // Transforma tipos automáticamente
}))
create(@Body() createUserDto: CreateUserDto) {
  return 'Usuario creado con validación estricta';
}

Para manejo de errores personalizado, los pipes pueden configurarse con mensajes específicos:

@Get(':id')
findOne(
  @Param('id', new ParseIntPipe({
    errorHttpStatusCode: HttpStatus.NOT_ACCEPTABLE
  })) 
  id: number
) {
  return `Usuario: ${id}`;
}

Los pipes también pueden combinarse para aplicar múltiples transformaciones y validaciones en secuencia:

@Get(':id')
findOne(
  @Param('id', ParseIntPipe, new DefaultValuePipe(1)) 
  id: number
) {
  return `Usuario: ${id}`;
}

Esta flexibilidad permite crear flujos de validación robustos que garantizan que los datos lleguen al controlador en el formato correcto y cumpliendo todas las reglas de negocio establecidas.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Nest

Documentación oficial de Nest
Alan Sastre - Autor del tutorial

Alan Sastre

Ingeniero de Software y formador, CEO en CertiDevs

Ingeniero de software especializado en Full Stack y en Inteligencia Artificial. Como CEO de CertiDevs, Nest es una de sus áreas de expertise. Con más de 15 años programando, 6K seguidores en LinkedIn y experiencia como formador, Alan se dedica a crear contenido educativo de calidad para desarrolladores de todos los niveles.

Más tutoriales de Nest

Explora más contenido relacionado con Nest y continúa aprendiendo con nuestros tutoriales gratuitos.

Aprendizajes de esta lección

  • Comprender qué son los pipes en NestJS y su función principal.
  • Aprender a utilizar los pipes integrados para validación y transformación de datos.
  • Aplicar pipes a diferentes niveles: parámetro, método y controlador.
  • Configurar opciones avanzadas de los pipes para personalizar su comportamiento.
  • Combinar múltiples pipes para crear flujos de validación robustos.