Express

Express

Tutorial Express: Validación de datos

Aprende a validar datos en Express con ejemplos de validación de parámetros, cuerpo y query para asegurar la integridad de tus aplicaciones.

Aprende Express y certifícate

Validación de entrada

La validación de entrada es un proceso fundamental que garantiza que los datos recibidos en nuestras rutas cumplan con los criterios esperados antes de ser procesados. En Express, podemos implementar validación directamente en nuestros controladores utilizando las capacidades nativas del framework y JavaScript.

Validación básica de parámetros

Express proporciona acceso directo a los datos de entrada a través de los objetos req.params, req.query y req.body. La validación manual nos permite verificar estos datos antes de continuar con la lógica de negocio:

app.get('/usuarios/:id', (req, res) => {
  const { id } = req.params;
  
  // Validar que el ID sea un número
  if (!id || isNaN(parseInt(id))) {
    return res.status(400).json({
      error: 'El ID debe ser un número válido'
    });
  }
  
  // Validar rango del ID
  const userId = parseInt(id);
  if (userId <= 0) {
    return res.status(400).json({
      error: 'El ID debe ser mayor que 0'
    });
  }
  
  // Continuar con la lógica
  res.json({ mensaje: `Usuario ${userId} encontrado` });
});

Validación de datos del cuerpo de la petición

Para validar datos enviados en el cuerpo de las peticiones POST o PUT, podemos crear funciones de validación específicas que verifiquen la estructura y contenido:

app.post('/usuarios', (req, res) => {
  const { nombre, email, edad } = req.body;
  
  // Validar campos requeridos
  if (!nombre || !email) {
    return res.status(400).json({
      error: 'Nombre y email son campos obligatorios'
    });
  }
  
  // Validar formato de email
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  if (!emailRegex.test(email)) {
    return res.status(400).json({
      error: 'El formato del email no es válido'
    });
  }
  
  // Validar edad si se proporciona
  if (edad !== undefined) {
    if (isNaN(parseInt(edad)) || parseInt(edad) < 0 || parseInt(edad) > 120) {
      return res.status(400).json({
        error: 'La edad debe ser un número entre 0 y 120'
      });
    }
  }
  
  // Procesar datos válidos
  res.status(201).json({
    mensaje: 'Usuario creado correctamente',
    usuario: { nombre, email, edad }
  });
});

Validación de parámetros de consulta

Los query parameters también requieren validación, especialmente cuando se utilizan para filtrado o paginación:

app.get('/productos', (req, res) => {
  const { categoria, precio_min, precio_max, limite } = req.query;
  
  // Validar categoría si se proporciona
  if (categoria && typeof categoria !== 'string') {
    return res.status(400).json({
      error: 'La categoría debe ser una cadena de texto'
    });
  }
  
  // Validar precios
  if (precio_min && (isNaN(parseFloat(precio_min)) || parseFloat(precio_min) < 0)) {
    return res.status(400).json({
      error: 'El precio mínimo debe ser un número positivo'
    });
  }
  
  if (precio_max && (isNaN(parseFloat(precio_max)) || parseFloat(precio_max) < 0)) {
    return res.status(400).json({
      error: 'El precio máximo debe ser un número positivo'
    });
  }
  
  // Validar que precio_min no sea mayor que precio_max
  if (precio_min && precio_max && parseFloat(precio_min) > parseFloat(precio_max)) {
    return res.status(400).json({
      error: 'El precio mínimo no puede ser mayor que el máximo'
    });
  }
  
  // Validar límite de resultados
  if (limite && (isNaN(parseInt(limite)) || parseInt(limite) <= 0 || parseInt(limite) > 100)) {
    return res.status(400).json({
      error: 'El límite debe ser un número entre 1 y 100'
    });
  }
  
  res.json({ mensaje: 'Filtros válidos aplicados' });
});

Funciones auxiliares para validación

Para mantener el código organizado y reutilizable, podemos crear funciones auxiliares que encapsulen la lógica de validación común:

// Función para validar email
function validarEmail(email) {
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return regex.test(email);
}

// Función para validar longitud de cadena
function validarLongitud(texto, min, max) {
  if (typeof texto !== 'string') return false;
  return texto.length >= min && texto.length <= max;
}

// Función para validar número en rango
function validarRango(numero, min, max) {
  const num = parseFloat(numero);
  return !isNaN(num) && num >= min && num <= max;
}

// Uso en las rutas
app.post('/perfil', (req, res) => {
  const { nombre, email, biografia } = req.body;
  
  if (!validarLongitud(nombre, 2, 50)) {
    return res.status(400).json({
      error: 'El nombre debe tener entre 2 y 50 caracteres'
    });
  }
  
  if (!validarEmail(email)) {
    return res.status(400).json({
      error: 'Email inválido'
    });
  }
  
  if (biografia && !validarLongitud(biografia, 0, 500)) {
    return res.status(400).json({
      error: 'La biografía no puede exceder 500 caracteres'
    });
  }
  
  res.json({ mensaje: 'Perfil actualizado correctamente' });
});

Validación de tipos de datos complejos

Para estructuras de datos más complejas, podemos implementar validaciones que verifiquen arrays y objetos anidados:

app.post('/pedidos', (req, res) => {
  const { cliente, productos, direccion } = req.body;
  
  // Validar estructura del cliente
  if (!cliente || typeof cliente !== 'object') {
    return res.status(400).json({
      error: 'Los datos del cliente son requeridos'
    });
  }
  
  if (!cliente.nombre || !cliente.telefono) {
    return res.status(400).json({
      error: 'Nombre y teléfono del cliente son obligatorios'
    });
  }
  
  // Validar array de productos
  if (!Array.isArray(productos) || productos.length === 0) {
    return res.status(400).json({
      error: 'Debe incluir al menos un producto'
    });
  }
  
  // Validar cada producto
  for (let i = 0; i < productos.length; i++) {
    const producto = productos[i];
    
    if (!producto.id || !producto.cantidad || !producto.precio) {
      return res.status(400).json({
        error: `Producto en posición ${i + 1} tiene datos incompletos`
      });
    }
    
    if (isNaN(parseInt(producto.cantidad)) || parseInt(producto.cantidad) <= 0) {
      return res.status(400).json({
        error: `Cantidad inválida en producto ${i + 1}`
      });
    }
  }
  
  res.status(201).json({ mensaje: 'Pedido creado correctamente' });
});

La validación de entrada en Express nos permite interceptar datos incorrectos antes de que lleguen a la lógica de negocio, proporcionando respuestas claras sobre los errores encontrados y manteniendo la integridad de nuestras aplicaciones.

Aprende Express online

Otras lecciones de Express

Accede a todas las lecciones de Express y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a Express y certifícate

Ejercicios de programación de Express

Evalúa tus conocimientos de esta lección Validación de datos con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.