8-Estructura final (solo web)-routes-ejs


text
mi-proyecto/
├── app.js
├── routes/
│   └── web.js            ← Router solo para vistas web
├── public/
│   └── (estáticos)
└── views/
    ├── index.ejs         ← Lista de productos
    └── producto-detalle.ejs ← Vista de un solo producto

🔧 Código actualizado (sin API)

1. routes/web.js – Solo rutas que renderizan HTML

javascript
const express = require('express');
const router = express.Router();

// Datos de ejemplo (simulan una base de datos)
const productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 },
  { id: 3, nombre: 'Teclado', precio: 50 }
];

// Ruta para ver todos los productos (vista index)
router.get('/productos', (req, res) => {
  res.render('index', { productos });
});

// Ruta para ver un solo producto (nueva vista de detalle)
router.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const producto = productos.find(p => p.id === id);
  
  if (!producto) {
    return res.status(404).render('error', { mensaje: 'Producto no encontrado' });
  }
  
  res.render('producto-detalle', { producto });
});

// También podemos redirigir la raíz a /productos
router.get('/', (req, res) => {
  res.redirect('/productos');
});

module.exports = router;

2. app.js – Monta el router y configura estáticos

javascript
const express = require('express');
const path = require('path');

const app = express();
const PORT = 3000;

// Configurar EJS
app.set('view engine', 'ejs');
// (Express ya busca en la carpeta 'views' por defecto)

// Archivos estáticos
app.use(express.static('public'));
app.use('/css', express.static('node_modules/bootstrap/dist/css'));
app.use('/js', express.static('node_modules/bootstrap/dist/js'));

// Importar el router web
const webRouter = require('./routes/web');

// Usar el router para TODAS las rutas (todo es web)
app.use('/', webRouter);

app.listen(PORT, () => {
  console.log(`🚀 Servidor web corriendo en http://localhost:${PORT}`);
  console.log(`📦 Ver productos: http://localhost:${PORT}/productos`);
});

3. views/index.ejs – Lista de productos (igual que antes)

html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Mi Tienda - Productos</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <h1 class="text-center">📦 Lista de Productos</h1>
        <div class="row mt-4">
            <div class="col-md-6 offset-md-3">
                <ul class="list-group">
                    <% productos.forEach(producto => { %>
                        <li class="list-group-item d-flex justify-content-between align-items-center">
                            <strong><%= producto.nombre %></strong> - $<%= producto.precio %>
                            <a href="/productos/<%= producto.id %>" class="btn btn-sm btn-primary">Ver detalle</a>
                        </li>
                    <% }) %>
                </ul>
            </div>
        </div>
    </div>
    <script src="/js/bootstrap.min.js"></script>
</body>
</html>

4. views/producto-detalle.ejs – Vista individual (nueva)

html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title><%= producto.nombre %> - Detalle</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <div class="card">
            <div class="card-header">
                <h2><%= producto.nombre %></h2>
            </div>
            <div class="card-body">
                <p><strong>ID:</strong> <%= producto.id %></p>
                <p><strong>Precio:</strong> $<%= producto.precio %></p>
                <p><strong>Descripción:</strong> (aquí iría la descripción real del producto)</p>
                <a href="/productos" class="btn btn-secondary">← Volver al listado</a>
            </div>
        </div>
    </div>
    <script src="/js/bootstrap.min.js"></script>
</body>
</html>

5. views/error.ejs – Página de error 404

html
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <title>Error</title>
    <link rel="stylesheet" href="/css/bootstrap.min.css">
</head>
<body>
    <div class="container mt-5">
        <div class="alert alert-danger">
            <h4>❌ <%= mensaje %></h4>
            <a href="/productos" class="btn btn-primary">Ir al inicio</a>
        </div>
    </div>
</body>
</html>

🧪 ¿Cómo queda la navegación?

  • http://localhost:3000/ → Redirige a /productos

  • http://localhost:3000/productos → Lista todos los productos (HTML)

  • http://localhost:3000/productos/1 → Página con detalle del producto 1 (HTML)

  • Ya no hay rutas que devuelvan JSON (se eliminaron por completo).

✅ ¿Por qué seguimos usando express.Router()?

  • Organización: las rutas web están en un archivo separado.

  • Escalabilidad: puedes agregar más rutas (carrito, checkout, etc.) sin llenar app.js.

  • Claridad: todo lo relacionado con la interfaz de usuario está en routes/web.js.

Ahora tu aplicación es 100% web, como esperabas. Si además quieres conservar algunas rutas API para un futuro, podrías montar otro router bajo el prefijo /api, pero según lo que pides, no es necesario.

¿Necesitas que también eliminemos el prefijo /productos y usemos rutas más amigables? Con gusto te ayudo.

Comentarios