¿Cuál es la diferencia entre `req.params`, `req.query` y `req.body` en Express?
Ver respuesta — intenta responderla en voz alta primero
Los tres traen datos del cliente, pero de lugares distintos de la petición:
req.params: los segmentos dinámicos de la ruta, definidos con:(por ejemplo/usuarios/:id→req.params.id).req.query: lo que viene después del?en la URL (por ejemplo?page=2→req.query.page).req.body: el cuerpo de la petición (el JSON de un POST o PUT). Necesita que activesapp.use(express.json()); si no,req.bodyesundefined.
Piensa en una URL como /usuarios/42?page=2 con un cuerpo JSON:
req.params→ la parte dentro de la ruta. Sirve para identificar qué recurso quieres: el usuario 42. Se define en el path con:, como/usuarios/:id. Llega siempre como string.req.query→ la parte después del?. Sirve para opciones o filtros: paginación, orden, búsqueda...?page=2&orden=nombreda{ page: "2", orden: "nombre" }. También llega como string.req.body→ no va en la URL, viaja en el cuerpo de la petición. Sirve para enviar datos grandes o sensibles: el objeto que quieres crear o actualizar. Es lo típico enPOSTyPUT.
Punto crítico del body: Express no lee el body por sí solo. Necesitas un middleware que lo parsee. Para JSON es app.use(express.json()). Sin esa línea, req.body será undefined aunque el cliente sí haya enviado datos.
Resumen mental:
- params = qué recurso (va en la ruta).
- query = cómo lo quieres (va tras el
?). - body = qué datos mandas (va en el cuerpo, requiere
express.json()).
const express = require("express");
const app = express();
// ¡IMPRESCINDIBLE para leer req.body como JSON!
// Sin esta línea, req.body sería undefined.
app.use(express.json());
// Ruta que usa los TRES a la vez:
// /usuarios/:id -> req.params.id
// ?notificar=true -> req.query.notificar
// cuerpo JSON -> req.body
app.put("/usuarios/:id", (req, res) => {
const id = req.params.id; // segmento de la ruta (string)
const notificar = req.query.notificar; // opción tras el ? (string)
const datos = req.body; // cuerpo JSON enviado
res.json({
mensaje: `Actualizando usuario ${id}`,
notificar: notificar, // "true" (string, no booleano)
datosRecibidos: datos, // { nombre: "Ana Actualizada" }
});
});
// Ejemplo de qué pasa SIN express.json() (para entender el error típico)
app.post("/sin-parser", (req, res) => {
// Si arriba NO tuvieras app.use(express.json()),
// req.body aquí sería undefined y esto reventaría al leer .nombre
res.json({ recibido: req.body });
});
app.listen(3000, () => {
console.log("Servidor en http://localhost:3000");
});
Probando con curl la ruta que usa los tres:
# id=42 (params), notificar=true (query), y un body JSON con el nombre
curl -X PUT "http://localhost:3000/usuarios/42?notificar=true" \
-H "Content-Type: application/json" \
-d '{"nombre":"Ana Actualizada"}'
# Respuesta esperada:
# {
# "mensaje": "Actualizando usuario 42",
# "notificar": "true",
# "datosRecibidos": { "nombre": "Ana Actualizada" }
# }
Olvidar app.use(express.json()) y luego preguntarse por qué req.body sale undefined. Este es probablemente el error número uno de los juniors con Express: envías un POST con JSON, intentas leer req.body.nombre y el servidor explota con "Cannot read properties of undefined". El problema no es tu ruta, es que falta el middleware que parsea el body. Otro descuido relacionado: no mandar el header Content-Type: application/json en la petición, porque express.json() solo parsea cuerpos marcados como JSON.
"Los tres traen datos del cliente pero de sitios distintos.
req.paramsson los segmentos dinámicos de la ruta, los que defino con dos puntos, como/usuarios/:id; sirven para identificar el recurso.req.queryes lo que viene después del?, como?page=2; lo uso para filtros y opciones. Yreq.bodyes el cuerpo de la petición, el JSON que mando en un POST o PUT. Lo importante del body es que Express no lo lee solo: necesitoapp.use(express.json()), y si me olvido de esa líneareq.bodysaleundefined. Además, params y query siempre llegan como string, así que si necesito un número lo convierto."
Tienes esta ruta y haces un POST con -d '{"nombre":"Ana"}', pero en la consola req.body sale undefined. ¿Qué falta?
const express = require("express");
const app = express();
app.post("/usuarios", (req, res) => {
console.log(req.body); // undefined
res.json({ creado: req.body });
});
app.listen(3000);
Ver respuesta
Falta registrar el middleware que parsea el JSON del cuerpo. Hay que añadir antes de las rutas:
app.use(express.json());
Express no lee el body por defecto; express.json() es quien lo interpreta y llena req.body. Sin él, req.body queda undefined aunque el cliente sí haya enviado datos. (También hay que asegurarse de enviar la petición con el header Content-Type: application/json, porque express.json() solo parsea cuerpos marcados como JSON.)