5-1-Express--Router Express.js

¿Qué es express.Router()?

Router() es un middleware de Express que te permite modularizar las rutas. En lugar de definir todas las rutas directamente en app.js, puedes agruparlas en archivos separados usando express.Router(). Esto hace el código más organizado, reutilizable y fácil de mantener.

Ventajas:

  • Separa las rutas por funcionalidad (ej: productos, usuarios, etc.).

  • Puedes aplicar middleware específico a un grupo de rutas.

  • El archivo principal (app.js) queda más limpio.


Implementación en tu ejemplo

Tu código actual tiene tres rutas relacionadas con productos: GET /, GET /productos/:id y POST /productos. Vamos a mover esas rutas a un router llamado productosRouter.

Estructura de archivos (sencilla)

text
mi-app/
├── app.js
├── routes/
│   └── productos.js      ← Aquí van las rutas agrupadas
└── package.json

Paso 1: Crear el archivo routes/productos.js

javascript
const express = require('express');
const router = express.Router();   // Crear un objeto router

// Arreglo de productos (lo movemos aquí para mantenerlo junto a las rutas)
let productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 },
  { id: 3, nombre: 'Teclado', precio: 50 }
];

// Ruta para ver todos (GET /)
router.get('/', (req, res) => {
  let lista = '';
  for (let i = 0; i < productos.length; i++) {
    lista += `
      <li>
        <strong>${productos[i].nombre}</strong> - $${productos[i].precio}
        (<a href="/productos/${productos[i].id}">Ver detalles</a>)
      </li>
    `;
  }

  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>Productos</title>
      <style>body { font-family: Arial; margin: 30px; } li { margin: 10px 0; }</style>
    </head>
    <body>
      <h1>📦 Lista de productos</h1>
      <ul>${lista}</ul>
      <hr>
      <h2>➕ Agregar producto</h2>
      <form action="/productos" method="POST">
        <input type="text" name="nombre" placeholder="Nombre" required>
        <input type="number" step="1" name="precio" placeholder="Precio" required>
        <button type="submit">Crear</button>
      </form>
    </body>
    </html>
  `);
});

// Ruta para ver detalle (GET /productos/:id)
router.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const producto = productos.find(p => p.id === id);

  if (!producto) {
    return res.send('<h1>404 - Producto no encontrado</h1><a href="/">Volver</a>');
  }

  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>${producto.nombre}</title>
      <style>body { font-family: Arial; margin: 30px; }</style>
    </head>
    <body>
      <h1>📄 Detalle del producto</h1>
      <p><strong>ID:</strong> ${producto.id}</p>
      <p><strong>Nombre:</strong> ${producto.nombre}</p>
      <p><strong>Precio:</strong> $${producto.precio}</p>
      <a href="/">← Volver al listado</a>
    </body>
    </html>
  `);
});

// Ruta para crear producto (POST /productos)
router.post('/productos', (req, res) => {
  const { nombre, precio } = req.body;
  if (!nombre || !precio) {
    return res.send('<h1>Error: faltan datos</h1><a href="/">Volver</a>');
  }

  const nuevoId = productos.length > 0 ? Math.max(...productos.map(p => p.id)) + 1 : 1;
  const nuevoProducto = { id: nuevoId, nombre, precio: parseFloat(precio) };
  productos.push(nuevoProducto);

  res.redirect('/');
});

// Exportar el router para usarlo en app.js
module.exports = router;

Paso 2: Modificar app.js para usar el router

javascript
const express = require('express');
const app = express();
const PORT = 3000;

// Middleware para leer datos de formularios (sigue igual)
app.use(express.urlencoded({ extended: true }));

// Importar el router de productos
const productosRouter = require('./routes/productos');

// Usar el router en la ruta base '/'
app.use('/', productosRouter);

// Iniciar servidor
app.listen(PORT, () => console.log(`Servidor en http://localhost:${PORT}`));

Explicación detallada

  1. En routes/productos.js:

    • Llamamos a express.Router() para crear un mini-aplicación de rutas.

    • Definimos las mismas rutas, pero sin el prefijo (solo /, /productos/:id, etc.). El prefijo se agregará al montar el router en app.js.

    • Exportamos el router con module.exports.

  2. En app.js:

    • Importamos el router con require('./routes/productos').

    • Usamos app.use('/', productosRouter). Esto significa que todas las rutas definidas en el router se montarán bajo el camino /. Como nuestras rutas empiezan con / y /productos, funcionan exactamente igual que antes.

  3. Comportamiento final: Es idéntico al original. La diferencia es organizativa: las rutas de productos están en un archivo separado.


Ventajas que notarás

  • app.js queda súper limpio: solo middlewares globales y montaje de routers.

  • Si en el futuro agregas más módulos (usuarios, pedidos, etc.), cada uno tendrá su propio router en su propio archivo.

  • Puedes aplicar middlewares específicos a un router (por ejemplo, autenticación solo para rutas de productos) sin afectar a otras rutas.


¿Qué pasa con la ruta raíz /?

Antes tenías app.get('/', ...). Ahora esa ruta está dentro del router, pero como el router se monta en /, la ruta interna / se convierte en / global. Funciona igual.


Versión final sin cambiar funcionalidad

Tu aplicación se comporta exactamente igual, pero ahora está modularizada. Los alumnos pueden ver que express.Router() es una forma sencilla de organizar el código.

Prueba: Ejecuta node app.js y abre http://localhost:3000. Verás la misma lista de productos, los mismos enlaces y el formulario funcionando igual

Comentarios

Entradas más populares de este blog

Cómo Iniciar un Proyecto Node.js

5-Express--Curso de Node.js#05 Introducción a Express.js

8-Template Engines