Menu

req.params, req.query y req.body en Express

req.params contiene las partes con nombre de la ruta (/users/:id), req.query el query string (?sort=new), y req.body el body de la petición ya parseado, que es undefined hasta que añades un parser como express.json().

Esta página incluye editores ejecutables: edita, ejecuta y ve el resultado al instante.

En Express, req.params contiene los valores de los segmentos con nombre de la ruta (/users/:id da req.params.id), req.query contiene el query string que va después del ? (/search?q=node da req.query.q), y req.body contiene los datos enviados en el body de la petición. req.params y req.query se rellenan en todas las peticiones, pero req.body sigue siendo undefined hasta que un parser como app.use(express.json()) lo lee. Los valores de params y query siempre son strings.

La primera petición responde {"params":{"userId":"7"},"query":{"sort":"new","limit":"2"}}. Fíjate en las comillas: 7 y 2 son strings, así que conviértelos con Number() antes de hacer cálculos o compararlos con números. Ahora cambia el método a POST, deja la ruta /users/7/posts y envía el body {"title": "Hello", "draft": true}: la respuesta es 201 con "body":{"title":"Hello","draft":true}, donde true es un booleano de verdad porque viene de JSON.

req.params vs req.query vs req.body

req.paramsreq.queryreq.body
Viene deLa ruta, /users/:idEl query string, ?sort=newEl body de la petición
URL o body de ejemplo/users/7/users?sort=new{"name": "Ada"}
Valor{ id: '7' }{ sort: 'new' }{ name: 'Ada' }
TiposStringsStrings y arrays de stringsLo que contenga el JSON
Necesita configuraciónUn :name en la rutaNadaapp.use(express.json())
Uso típicoQué recursoFiltrar, ordenar, paginarDatos para crear o actualizar

Una ruta puede tener varios parámetros, y cada nombre se convierte en una clave de req.params: /teams/:teamId/members/:memberId da los dos ids. Un guion o un punto también los separan, así que /flights/:from-:to convierte /flights/LAX-SFO en { from: 'LAX', to: 'SFO' }.

req.query con claves repetidas y ausentes

Una clave que aparece dos veces se convierte en un array, y una clave que falta es undefined, así que dale un valor por defecto a las opciones:

La respuesta es {"page":1,"tags":["red","sale"],"raw":{"tag":["red","sale"]}}. Envía GET /products?tag=red&page=3 y tags sigue siendo un array, ["red"], porque [].concat() convierte en array tanto un string como un array. Express 5 parsea los query strings con el parser simple de Node, así que ?filter[size]=m da la clave "filter[size]", no un objeto anidado; Express 4 sí lo anidaba.

req.body necesita express.json()

Node entrega el body como un stream de bytes. express.json() lo lee, lo parsea y rellena req.body, pero solo cuando la petición lleva Content-Type: application/json. Los formularios HTML envían application/x-www-form-urlencoded, que necesita express.urlencoded().

Envía POST /signup con el body {"email": "ada@example.com"} y obtienes 201 con {"email":"ada@example.com","name":"anonymous"}. Envía un body vacío y obtienes 400. El ?? {} importa: sin él, desestructurar undefined lanza un TypeError en cualquier petición que no tenga body JSON. Para validar de verdad la forma y los tipos, usa una librería de esquemas como zod.

req.headers y req.get()

req.headers es un objeto con todos los headers de la petición, con los nombres en minúsculas. req.get(name) lee un header ignorando mayúsculas, así que req.get('Content-Type') y req.get('content-type') devuelven lo mismo. Otras propiedades que vas a usar:

path es /whoami y originalUrl es /whoami?debug=1. Añade el header Authorization: Bearer abc en la barra de petición y vuelve a enviarla: token pasa a ser "Bearer abc". Dentro de un router montado con app.use('/api', router), req.path pierde el prefijo /api mientras que req.originalUrl lo conserva (rutas en Express explica cómo se monta).

Errores comunes

Leer req.body en una petición GET. Los navegadores y la mayoría de los clientes no envían body con GET. Pon las opciones de un GET en el query string.

Comprobar un flag del query como truthy. ?admin=false da el string 'false', que es truthy, así que if (req.query.admin) pasa. Compara strings: req.query.admin === 'true'.

Enviar JSON sin el header. Un cliente que envía JSON como text/plain obtiene req.body === undefined. Pon Content-Type: application/json en el cliente.

Preguntas frecuentes

¿Cómo obtengo la IP del cliente en Express?

Lee req.ip. Detrás de un proxy o un balanceador de carga es la dirección del proxy hasta que pones app.set('trust proxy', 1), que hace que Express lea el header X-Forwarded-For.

¿Cómo obtengo la URL completa de una petición en Express?

req.originalUrl es la ruta más el query string tal como los envió el cliente. Construye la URL absoluta con `${req.protocol}://${req.get('host')}${req.originalUrl}`.

¿Cómo manejo la subida de archivos en Express?

Los archivos llegan como multipart/form-data, que express.json() y express.urlencoded() no parsean. Usa un paquete como multer, que pone los archivos en req.file o req.files y los demás campos en req.body.

¿Cómo leo una cookie de la petición?

El header en bruto está en req.get('cookie'). Para tener un objeto en req.cookies, instala el paquete cookie-parser y añade app.use(cookieParser()).

Ilustración de los lenguajes de programación de Coddy

Aprende a programar con Coddy

Comenzar