5-4-MVC

¡Excelente! Aquí tienes la versión MVC sin rutas separadas, manteniendo la misma simplicidad pero organizado en modelo, vista y controlador, todo integrado desde app.js.

📁 Estructura del proyecto (sin carpeta routes)

text
mvc-sin-routes/
├── app.js
├── models/
│   └── productoModel.js
├── views/
│   └── productoView.js
└── controllers/
    └── productoController.js

1. Modelo (models/productoModel.js)

javascript
// Base de datos en memoria
let productos = [
  { id: 1, nombre: 'Laptop', precio: 1000 },
  { id: 2, nombre: 'Mouse', precio: 25 },
  { id: 3, nombre: 'Teclado', precio: 50 }
];

// Obtener todos
const getAll = () => productos;

// Obtener por ID
const getById = (id) => productos.find(p => p.id === id);

// Crear nuevo producto
const create = (nombre, precio) => {
  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);
  return nuevoProducto;
};

module.exports = { getAll, getById, create };

2. Vista (views/productoView.js)

javascript
// Vista: listado completo + formulario
const listadoView = (productos) => {
  let listaItems = '';
  for (let p of productos) {
    listaItems += `
      <li>
        <strong>${p.nombre}</strong> - $${p.precio}
        (<a href="/productos/${p.id}">Ver detalles</a>)
      </li>
    `;
  }

  return `
    <!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>${listaItems}</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>
  `;
};

// Vista: detalle de un producto
const detalleView = (producto) => `
  <!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>
`;

// Vista: error 404
const error404View = () => `
  <!DOCTYPE html>
  <html>
  <head><title>Error 404</title></head>
  <body>
    <h1>404 - Producto no encontrado</h1>
    <a href="/">Volver</a>
  </body>
  </html>
`;

// Vista: error por datos faltantes
const errorDatosView = () => `
  <!DOCTYPE html>
  <html>
  <head><title>Error</title></head>
  <body>
    <h1>Error: faltan nombre o precio</h1>
    <a href="/">Volver</a>
  </body>
  </html>
`;

module.exports = { listadoView, detalleView, error404View, errorDatosView };

3. Controlador (controllers/productoController.js)

javascript
const model = require('../models/productoModel');
const view = require('../views/productoView');

// GET / - Mostrar todos los productos
const listar = (req, res) => {
  const productos = model.getAll();
  res.send(view.listadoView(productos));
};

// GET /productos/:id - Mostrar detalle
const mostrarDetalle = (req, res) => {
  const id = parseInt(req.params.id);
  const producto = model.getById(id);
  if (!producto) {
    return res.status(404).send(view.error404View());
  }
  res.send(view.detalleView(producto));
};

// POST /productos - Crear producto
const crear = (req, res) => {
  const { nombre, precio } = req.body;
  if (!nombre || !precio) {
    return res.status(400).send(view.errorDatosView());
  }
  model.create(nombre, precio);
  res.redirect('/');
};

module.exports = { listar, mostrarDetalle, crear };

4. Aplicación principal (app.js) - sin archivo de rutas

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

// Importar el controlador (ya tiene la lógica)
const controller = require('./controllers/productoController');

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

// ---------- RUTAS DEFINIDAS DIRECTAMENTE ----------
app.get('/', controller.listar);
app.get('/productos/:id', controller.mostrarDetalle);
app.post('/productos', controller.crear);

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

▶️ Cómo ejecutar

  1. Crear la estructura de carpetas y archivos.

  2. Instalar Express:

    bash
    npm init -y
    npm install express
  3. Ejecutar:

    bash
    node app.js
  4. Abrir http://localhost:3000 y probar.


✅ ¿Qué aprenden con esta versión?

  • Patrón MVC sin la complejidad adicional de un enrutador separado.

  • Separación de responsabilidades en modelos, vistas y controladores.

  • Las rutas están en app.js pero el controlador maneja la lógica.

  • Fácil de entender para alumnos que dan sus primeros pasos en arquitectura MVC.

Es exactamente igual en funcionalidad al ejercicio original, pero con el código organizado en capas. ¡Perfecto para enseñar MVC de forma gradual

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