← Node & Express

Fundamentos de Express

¿Qué es el routing en Express y cómo defines rutas con parámetros dinámicos como `/usuarios/:id`?

Ver respuesta — intenta responderla en voz alta primero

Routing es decidir qué código responde según el método HTTP y la URL de la petición. En Express defines rutas con métodos como app.get, app.post, app.put y app.delete, pasándoles una ruta y una función manejadora (req, res) => {}. Para partes dinámicas de la URL usas route params con dos puntos, por ejemplo /usuarios/:id, y los lees en req.params.id.

Una ruta en Express tiene tres piezas:

  • El método HTTP: app.get (leer), app.post (crear), app.put (actualizar), app.delete (borrar).
  • El path (la URL): un string como "/usuarios" o "/usuarios/:id".
  • El handler: la función (req, res) => {} que se ejecuta cuando esa combinación coincide.

Sobre los route params:

  • Un segmento que empieza con : es un comodín que captura lo que venga ahí.
  • En /usuarios/:id, si alguien pide /usuarios/42, entonces req.params.id vale "42".
  • Ojo: los params siempre llegan como string, aunque parezcan números.
  • Puedes tener varios: /usuarios/:userId/posts/:postId da req.params.userId y req.params.postId.

Express evalúa las rutas en el orden en que las declaras y usa la primera que coincida.

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

// Middleware necesario para leer JSON del body en el POST (más abajo lo usamos)
app.use(express.json());

// "Base de datos" en memoria para el ejemplo
let usuarios = [
  { id: 1, nombre: "Ana" },
  { id: 2, nombre: "Luis" },
];

// GET /usuarios -> devuelve TODOS los usuarios
app.get("/usuarios", (req, res) => {
  res.json(usuarios);
});

// GET /usuarios/:id -> devuelve UN usuario según el id de la URL
app.get("/usuarios/:id", (req, res) => {
  // req.params.id llega como string, lo convertimos a número
  const id = Number(req.params.id);
  const usuario = usuarios.find((u) => u.id === id);

  // Si no existe, respondemos 404
  if (!usuario) {
    return res.status(404).json({ error: "Usuario no encontrado" });
  }

  res.json(usuario);
});

// POST /usuarios -> crea un usuario nuevo con los datos del body
app.post("/usuarios", (req, res) => {
  const nuevo = {
    id: usuarios.length + 1,
    nombre: req.body.nombre,
  };
  usuarios.push(nuevo);

  // 201 = "Created", la respuesta correcta al crear un recurso
  res.status(201).json(nuevo);
});

app.listen(3000, () => {
  console.log("Servidor en http://localhost:3000");
});

Puedes probar las rutas con curl:

# Traer todos los usuarios
curl http://localhost:3000/usuarios

# Traer el usuario con id 1
curl http://localhost:3000/usuarios/1

# Crear un usuario nuevo (enviando JSON en el body)
curl -X POST http://localhost:3000/usuarios \
  -H "Content-Type: application/json" \
  -d '{"nombre":"Marta"}'

Confundir el orden de las rutas o pensar que req.params.id es un número. Dos fallos típicos:

  • Comparar req.params.id === 1 (número) cuando en realidad es "1" (string). Siempre conviértelo con Number(...) antes de comparar.
  • Declarar una ruta específica después de una genérica. Por ejemplo, si pones /usuarios/:id antes que /usuarios/nuevo, la petición a /usuarios/nuevo caerá en :id con id = "nuevo". Las rutas fijas y específicas van antes que las dinámicas.

"Routing es asociar un método HTTP más una URL a una función que responde. En Express uso app.get, app.post, app.put y app.delete, pasándoles el path y un handler (req, res). Para partes dinámicas de la URL uso route params con dos puntos, como /usuarios/:id, y los leo en req.params.id. Algo importante: los params siempre llegan como string, así que si necesito comparar contra un id numérico lo convierto con Number. También cuido el orden: Express usa la primera ruta que coincide, así que las rutas específicas van antes que las dinámicas."

Reto rápido

Tienes estas dos rutas declaradas en este orden:

app.get("/productos/:id", (req, res) => res.send("dinámica"));
app.get("/productos/ofertas", (req, res) => res.send("ofertas"));

Si alguien pide GET /productos/ofertas, ¿qué responde y por qué? ¿Cómo lo arreglas?

Ver respuesta

Responde "dinámica". Como Express evalúa las rutas en orden y usa la primera que coincide, /productos/:id captura ofertas en req.params.id antes de llegar a la ruta específica. La segunda ruta nunca se ejecuta.

Se arregla declarando la ruta específica antes que la dinámica:

app.get("/productos/ofertas", (req, res) => res.send("ofertas"));
app.get("/productos/:id", (req, res) => res.send("dinámica"));