¡Ven a la JSConf España 2026! Comprar entradas

Filtrar usuarios con query params

En esta clase damos un paso clave para que nuestra API empiece a comportarse como una API real. Vamos a filtrar y limitar usuarios usando query params, algo imprescindible cuando trabajas con listados grandes.

El objetivo es poder hacer cosas como:

GET /users?limit=2
GET /users?limit=10&offset=20

Y que la API responda correctamente sin “romperse”.

El problema inicial

Tenemos una ruta /users que devuelve todos los usuarios. Todo funciona bien… hasta que añadimos query params.

El problema aparece cuando:

  1. Comparamos la URL completa en lugar del pathname.
  2. Añadimos cualquier ?limit=... y la API devuelve un 404 Not Found.

Esto pasa porque la URL incluye la query string, pero nuestra lógica de rutas actual solo espera el path exacto. Resultado: la API se rompe con cualquier filtro.

Separar pathname y query string

La solución empieza por no comparar la URL completa, sino solo el pathname.

La URL real tiene esta forma: /users?limit=2

Pero lo que debemos comparar es solo: /users

Separando correctamente:

  • pathname: para las rutas.
  • query string: para los filtros.

Podemos usar el constructor URL de Node.js para esto:

const { pathname, searchParams } = new URL(req.url, `http://${req.headers.host}`)

Con esto evitamos que la API falle cuando se añaden parámetros.

Leer los query params correctamente

Una vez separado el pathname, el siguiente paso es leer los query params de forma segura. Para ello usamos URLSearchParams (disponible en searchParams), que nos permite:

  • Acceder fácilmente a los parámetros.
  • Evitar parseos manuales.
  • Tener una API clara y mantenible.

Ejemplo:

const limit = searchParams.get('limit')
const offset = searchParams.get('offset')

Ojo: los query params siempre son strings

Este punto es crítico. Aunque hagas /users?limit=2, el valor que llega al servidor es "2". No es un número, es un string.

Por eso es obligatorio:

  1. Convertir a número.
  2. Validar el resultado.
  3. Evitar errores silenciosos.

Regla de oro: Si no conviertes y validas, tarde o temprano tendrás bugs difíciles de detectar.

Limitar resultados con limit

Una vez convertido limit a número, ya podemos usarlo para limitar usuarios. La lógica es simple:

  • Si hay limit, se aplica (por ejemplo, con .slice()).
  • Si no hay limit, se devuelven todos.

Esto nos permite:

  • Reducir la cantidad de datos enviados.
  • Mejorar el rendimiento.
  • Preparar la API para paginación.

Añadir offset para paginación

Con offset damos el siguiente paso: paginación real. Gracias a limit y offset podemos:

  • Saltar elementos iniciales.
  • Devolver bloques de resultados.
  • Implementar páginas en el frontend fácilmente.

Y lo mejor: con muy pocas líneas de código usando .slice(offset, offset + limit).

Validar los parámetros

Nunca confíes en lo que llega por query string. Algunas buenas prácticas:

  • Convertir siempre a número (Number()).
  • Comprobar si es NaN (Number.isNaN()).
  • Decidir qué hacer si el valor no es válido:
    • Ignorar el parámetro.
    • Usar un valor por defecto.
    • Devolver un error al cliente.

Aunque en esta clase se muestra una validación básica, la idea clave es clara: hay que validar.

Qué hemos conseguido

Con muy poco código ahora podemos:

  • Filtrar usuarios.
  • Limitar resultados.
  • Paginar.
  • Evitar que la API se rompa con query params.
  • Preparar la base para endpoints más complejos.

Todo esto es fundamental para cualquier backend serio.

Conclusión

En esta clase has aprendido que:

  • No se debe comparar la URL completa para el enrutamiento.
  • El pathname y la query string son conceptos distintos.
  • Los query params siempre llegan como strings.
  • Hay que convertir y validar los valores.
  • limit y offset son la base de la paginación.

En la siguiente clase seguiremos mejorando la API y haciéndola más robusta y realista.