Parámetros y query strings

Intermedio
Express
Express
Actualizado: 20/06/2025

Parámetros de ruta (:id)

Los parámetros de ruta permiten capturar valores dinámicos directamente desde la URL, convirtiéndola en una plantilla flexible que puede manejar múltiples recursos similares. En lugar de crear rutas estáticas para cada elemento individual, Express permite definir segmentos variables en la ruta utilizando dos puntos seguidos del nombre del parámetro.

La sintaxis básica utiliza el prefijo : seguido del nombre que queremos asignar al parámetro. Cuando Express procesa una solicitud, extrae automáticamente estos valores y los hace disponibles a través del objeto req.params.

const express = require('express');
const app = express();

// Parámetro simple para capturar un ID
app.get('/usuarios/:id', (req, res) => {
  const userId = req.params.id;
  res.json({ 
    mensaje: `Datos del usuario ${userId}`,
    parametro: userId 
  });
});

app.listen(3000);

En este ejemplo, cualquier solicitud a /usuarios/123, /usuarios/abc o /usuarios/usuario-premium capturará el valor después de /usuarios/ y lo asignará a req.params.id. Los parámetros son siempre strings, independientemente de si el valor parece numérico.

Múltiples parámetros en una ruta

Express permite definir varios parámetros en la misma ruta, cada uno identificado con su propio nombre. Esto resulta especialmente útil para estructuras de recursos anidados o jerarquías complejas.

// Múltiples parámetros para recursos anidados
app.get('/usuarios/:userId/posts/:postId', (req, res) => {
  const { userId, postId } = req.params;
  
  res.json({
    usuario: userId,
    publicacion: postId,
    ruta: `Usuario ${userId}, Post ${postId}`
  });
});

// Parámetros con diferentes niveles de anidamiento
app.get('/tiendas/:tiendaId/productos/:categoria/:productoId', (req, res) => {
  const { tiendaId, categoria, productoId } = req.params;
  
  res.json({
    tienda: tiendaId,
    categoria: categoria,
    producto: productoId
  });
});

Cuando se accede a /usuarios/42/posts/128, Express asigna automáticamente 42 a userId y 128 a postId. La destructuración del objeto req.params simplifica el acceso a múltiples parámetros simultáneamente.

Validación y transformación de parámetros

Aunque los parámetros llegan como strings, frecuentemente necesitamos validarlos o transformarlos antes de utilizarlos en la lógica de negocio. Express 5 facilita estas operaciones directamente en el manejador de ruta.

// Validación de parámetros numéricos
app.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  
  // Validación básica
  if (isNaN(id) || id <= 0) {
    return res.status(400).json({ 
      error: 'ID debe ser un número positivo' 
    });
  }
  
  res.json({ 
    producto: `Producto con ID ${id}`,
    tipo: typeof id 
  });
});

// Validación de formato específico
app.get('/usuarios/:username', (req, res) => {
  const { username } = req.params;
  
  // Validar formato de username (solo letras y números)
  const formatoValido = /^[a-zA-Z0-9]+$/.test(username);
  
  if (!formatoValido) {
    return res.status(400).json({ 
      error: 'Username solo puede contener letras y números' 
    });
  }
  
  res.json({ usuario: username });
});

Parámetros opcionales y comodines

Express permite crear patrones más flexibles utilizando parámetros opcionales y comodines. Los parámetros opcionales se definen añadiendo ? después del nombre del parámetro, mientras que los comodines capturan múltiples segmentos de ruta.

// Parámetro opcional
app.get('/archivos/:carpeta/:archivo?', (req, res) => {
  const { carpeta, archivo } = req.params;
  
  if (archivo) {
    res.json({ 
      mensaje: `Archivo ${archivo} en carpeta ${carpeta}` 
    });
  } else {
    res.json({ 
      mensaje: `Listando contenido de carpeta ${carpeta}` 
    });
  }
});

// Comodín para capturar rutas anidadas
app.get('/docs/*', (req, res) => {
  const rutaCompleta = req.params[0]; // El comodín se almacena en índice 0
  res.json({ 
    ruta: rutaCompleta,
    segmentos: rutaCompleta.split('/')
  });
});

La ruta /archivos/imagenes funcionará sin el parámetro archivo, mientras que /archivos/imagenes/foto.jpg capturará ambos valores. El comodín * en /docs/* captura todo lo que venga después de /docs/, permitiendo manejar estructuras de carpetas dinámicas.

Casos de uso prácticos

Los parámetros de ruta resultan fundamentales para construir APIs RESTful y aplicaciones que manejan recursos dinámicos. Su implementación correcta mejora tanto la experiencia del usuario como la organización del código.

// API RESTful con parámetros
app.get('/api/clientes/:id', (req, res) => {
  const clienteId = req.params.id;
  // Simular búsqueda en base de datos
  res.json({ 
    id: clienteId, 
    nombre: `Cliente ${clienteId}` 
  });
});

app.put('/api/clientes/:id', (req, res) => {
  const clienteId = req.params.id;
  // Lógica de actualización
  res.json({ 
    mensaje: `Cliente ${clienteId} actualizado` 
  });
});

// Rutas para diferentes formatos de respuesta
app.get('/reportes/:tipo/:formato', (req, res) => {
  const { tipo, formato } = req.params;
  
  const formatosPermitidos = ['json', 'xml', 'csv'];
  
  if (!formatosPermitidos.includes(formato)) {
    return res.status(400).json({ 
      error: 'Formato no soportado',
      formatos: formatosPermitidos 
    });
  }
  
  res.json({ 
    reporte: tipo, 
    formato: formato,
    datos: `Reporte ${tipo} en formato ${formato}` 
  });
});

Los parámetros de ruta proporcionan la flexibilidad necesaria para crear aplicaciones escalables que pueden manejar recursos dinámicos sin requerir rutas hardcodeadas para cada posible valor. Su correcta implementación es esencial para el desarrollo de aplicaciones web modernas con Express.

Query strings (?name=value)

Los query strings proporcionan un mecanismo para enviar datos adicionales a través de la URL utilizando pares clave-valor que aparecen después del símbolo ?. A diferencia de los parámetros de ruta que forman parte de la estructura de la URL, los query strings son opcionales y permiten filtrar, ordenar o configurar el comportamiento de una ruta sin modificar su definición básica.

Express procesa automáticamente los query strings y los hace disponibles a través del objeto req.query, donde cada parámetro se convierte en una propiedad del objeto. La sintaxis básica sigue el formato ?clave=valor, y múltiples parámetros se separan con el símbolo &.

const express = require('express');
const app = express();

// Ruta que acepta query strings
app.get('/productos', (req, res) => {
  const { categoria, precio, ordenar } = req.query;
  
  res.json({
    filtros: {
      categoria: categoria || 'todas',
      precio: precio || 'cualquiera',
      ordenar: ordenar || 'nombre'
    },
    url: req.url
  });
});

app.listen(3000);

Una solicitud a /productos?categoria=electronica&precio=100&ordenar=precio extraerá automáticamente los valores y los asignará a las propiedades correspondientes en req.query. Si un parámetro no está presente, su valor será undefined.

Manejo de múltiples valores

Los query strings pueden contener múltiples valores para la misma clave, lo que resulta útil para filtros complejos o selecciones múltiples. Express maneja estos casos convirtiendo automáticamente los valores repetidos en arrays.

// Manejo de valores múltiples
app.get('/buscar', (req, res) => {
  const { tags, formato } = req.query;
  
  // Si hay múltiples valores, Express crea un array automáticamente
  const tagsArray = Array.isArray(tags) ? tags : [tags].filter(Boolean);
  
  res.json({
    tags: tagsArray,
    formato: formato,
    cantidad: tagsArray.length
  });
});

Una URL como /buscar?tags=javascript&tags=nodejs&tags=express&formato=json generará un array ['javascript', 'nodejs', 'express'] para la propiedad tags, mientras que formato mantendrá el valor único 'json'.

Validación y transformación de query strings

Los valores de query strings siempre llegan como strings, incluso cuando representan números o booleanos. Es fundamental validar y transformar estos valores según las necesidades de la aplicación.

// Validación y transformación de tipos
app.get('/api/usuarios', (req, res) => {
  const { 
    pagina = '1', 
    limite = '10', 
    activo, 
    buscar 
  } = req.query;
  
  // Transformar y validar números
  const paginaNum = parseInt(pagina);
  const limiteNum = parseInt(limite);
  
  if (isNaN(paginaNum) || paginaNum < 1) {
    return res.status(400).json({ 
      error: 'Página debe ser un número mayor a 0' 
    });
  }
  
  if (isNaN(limiteNum) || limiteNum < 1 || limiteNum > 100) {
    return res.status(400).json({ 
      error: 'Límite debe estar entre 1 y 100' 
    });
  }
  
  // Transformar booleanos
  const esActivo = activo === 'true' ? true : 
                   activo === 'false' ? false : null;
  
  res.json({
    paginacion: {
      pagina: paginaNum,
      limite: limiteNum
    },
    filtros: {
      activo: esActivo,
      buscar: buscar || null
    }
  });
});

Combinación con parámetros de ruta

Los query strings se combinan perfectamente con los parámetros de ruta, permitiendo crear APIs flexibles que manejan tanto identificación de recursos como configuración adicional.

// Combinando parámetros de ruta con query strings
app.get('/usuarios/:id/posts', (req, res) => {
  const { id } = req.params;
  const { 
    estado = 'publicado', 
    desde, 
    hasta, 
    incluir 
  } = req.query;
  
  // Validar parámetro de ruta
  const userId = parseInt(id);
  if (isNaN(userId)) {
    return res.status(400).json({ 
      error: 'ID de usuario inválido' 
    });
  }
  
  // Procesar fechas si están presentes
  const filtroFecha = {};
  if (desde) {
    const fechaDesde = new Date(desde);
    if (!isNaN(fechaDesde)) {
      filtroFecha.desde = fechaDesde;
    }
  }
  
  if (hasta) {
    const fechaHasta = new Date(hasta);
    if (!isNaN(fechaHasta)) {
      filtroFecha.hasta = fechaHasta;
    }
  }
  
  res.json({
    usuario: userId,
    filtros: {
      estado,
      fechas: filtroFecha,
      incluir: incluir ? incluir.split(',') : []
    }
  });
});

Una solicitud a /usuarios/123/posts?estado=borrador&desde=2024-01-01&incluir=comentarios,likes combina la identificación del usuario específico con filtros opcionales para personalizar la respuesta.

Casos de uso avanzados

Los query strings resultan especialmente útiles para implementar funcionalidades de búsqueda, paginación y filtrado que son comunes en aplicaciones web modernas.

// Sistema de búsqueda y filtrado completo
app.get('/tienda/productos', (req, res) => {
  const {
    q: termino,           // término de búsqueda
    cat: categoria,       // categoría
    min: precioMin,       // precio mínimo
    max: precioMax,       // precio máximo
    sort: ordenar = 'nombre',  // ordenamiento
    dir: direccion = 'asc',    // dirección del ordenamiento
    page: pagina = '1',        // página actual
    size: tamaño = '20'        // elementos por página
  } = req.query;
  
  // Construir objeto de filtros
  const filtros = {};
  
  if (termino) {
    filtros.busqueda = termino.trim();
  }
  
  if (categoria) {
    filtros.categoria = categoria;
  }
  
  // Validar rangos de precio
  if (precioMin) {
    const min = parseFloat(precioMin);
    if (!isNaN(min) && min >= 0) {
      filtros.precioMinimo = min;
    }
  }
  
  if (precioMax) {
    const max = parseFloat(precioMax);
    if (!isNaN(max) && max > 0) {
      filtros.precioMaximo = max;
    }
  }
  
  // Validar ordenamiento
  const ordenamientosValidos = ['nombre', 'precio', 'fecha', 'popularidad'];
  const direccionesValidas = ['asc', 'desc'];
  
  const ordenFinal = ordenamientosValidos.includes(ordenar) ? ordenar : 'nombre';
  const direccionFinal = direccionesValidas.includes(direccion) ? direccion : 'asc';
  
  res.json({
    filtros,
    ordenamiento: {
      campo: ordenFinal,
      direccion: direccionFinal
    },
    paginacion: {
      pagina: parseInt(pagina) || 1,
      tamaño: Math.min(parseInt(tamaño) || 20, 100)
    }
  });
});

Este enfoque permite URLs como /tienda/productos?q=laptop&cat=electronica&min=500&max=2000&sort=precio&dir=desc&page=2&size=15, proporcionando una interfaz flexible para consultas complejas sin requerir múltiples endpoints específicos.

Los query strings ofrecen la ventaja de ser completamente opcionales y autodocumentados en la URL, facilitando tanto el desarrollo como el debugging de aplicaciones Express.

Fuentes y referencias

Documentación oficial y recursos externos para profundizar en Express

Documentación oficial de Express
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, Express 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 Express

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

Aprendizajes de esta lección

  • Comprender qué son y cómo se utilizan los parámetros de ruta en Express.
  • Aprender a capturar y validar múltiples parámetros en rutas anidadas.
  • Conocer el uso de parámetros opcionales y comodines para rutas flexibles.
  • Entender qué son los query strings y cómo acceder a ellos mediante req.query.
  • Aplicar validaciones y transformaciones a parámetros y query strings para mejorar la robustez de las aplicaciones.