Versión MVC del ejercicio completo-router

 

Versión MVC del ejercicio completo

Aquí tienes el ejercicio refactorizado a MVC con organización por capas:

📁 ESTRUCTURA DEL PROYECTO

text
mi-app-mvc/
├── models/
│   └── Producto.js
├── controllers/
│   └── productoController.js
├── views/
│   ├── index.ejs
│   └── productos.ejs
├── public/
│   └── (archivos estáticos)
├── routes/
│   └── productoRoutes.js
└── app.js

📄 CÓDIGO COMPLETO

1️⃣ models/Producto.js (Modelo - Datos)

javascript
// Modelo: Maneja toda la lógica de datos
class Producto {
    constructor() {
        this.productos = [
            { id: 1, nombre: 'Laptop', precio: 1000 },
            { id: 2, nombre: 'Mouse', precio: 25 },
            { id: 3, nombre: 'Teclado', precio: 50 }
        ];
        this.contadorId = 4;
    }

    // Obtener todos los productos
    obtenerTodos() {
        return this.productos;
    }

    // Obtener producto por ID
    obtenerPorId(id) {
        return this.productos.find(p => p.id === id);
    }

    // Crear nuevo producto
    crear(nombre, precio) {
        const nuevoProducto = {
            id: this.contadorId++,
            nombre: nombre.trim(),
            precio: parseFloat(precio)
        };
        this.productos.push(nuevoProducto);
        return nuevoProducto;
    }

    // Obtener cantidad total
    obtenerTotal() {
        return this.productos.length;
    }
}

module.exports = new Producto();

2️⃣ controllers/productoController.js (Controlador - Lógica)

javascript
const Producto = require('../models/Producto');

class ProductoController {
    
    // GET / - Renderizar vista principal (index)
    mostrarInicio(req, res) {
        const productos = Producto.obtenerTodos();
        res.render('index', {
            title: 'Mi Tienda',
            productos: productos
        });
    }

    // GET /productos-vista - Renderizar vista de productos
    mostrarProductosVista(req, res) {
        const productos = Producto.obtenerTodos();
        const total = Producto.obtenerTotal();
        
        res.render('productos', {
            title: 'Lista de Productos',
            productos: productos,
            total: total
        });
    }

    // GET /productos - API: Devolver todos (JSON)
    obtenerTodosAPI(req, res) {
        const productos = Producto.obtenerTodos();
        res.json(productos);
    }

    // GET /productos/:id - API: Devolver uno (JSON)
    obtenerUnoAPI(req, res) {
        const id = parseInt(req.params.id);
        const producto = Producto.obtenerPorId(id);
        
        if (!producto) {
            return res.status(404).json({ 
                error: 'Producto no encontrado' 
            });
        }
        
        res.json(producto);
    }

    // POST /productos-formulario - Procesar formulario
    procesarFormulario(req, res) {
        const { nombre, precio } = req.body;
        
        // Validaciones
        if (!nombre || !precio) {
            return res.status(400).send(`
                <h1>Error</h1>
                <p>Faltan datos: nombre y precio son obligatorios</p>
                <a href="/">Volver al inicio</a>
            `);
        }
        
        if (nombre.trim().length < 3) {
            return res.status(400).send(`
                <h1>Error</h1>
                <p>El nombre debe tener al menos 3 caracteres</p>
                <a href="/">Volver al inicio</a>
            `);
        }
        
        if (isNaN(precio) || parseFloat(precio) <= 0) {
            return res.status(400).send(`
                <h1>Error</h1>
                <p>El precio debe ser un número mayor a 0</p>
                <a href="/">Volver al inicio</a>
            `);
        }
        
        // Crear producto
        Producto.crear(nombre, precio);
        
        // Redirigir a la página principal
        res.redirect('/');
    }
}

module.exports = new ProductoController();

3️⃣ routes/productoRoutes.js (Rutas - Endpoints)

javascript
const express = require('express');
const productoController = require('../controllers/productoController');

const router = express.Router();

// ============ RUTAS WEB (Vistas EJS) ============
router.get('/', productoController.mostrarInicio);
router.get('/productos-vista', productoController.mostrarProductosVista);

// ============ RUTAS API (JSON) ============
router.get('/productos', productoController.obtenerTodosAPI);
router.get('/productos/:id', productoController.obtenerUnoAPI);

// ============ RUTA PARA FORMULARIOS ============
router.post('/productos-formulario', productoController.procesarFormulario);

module.exports = router;

4️⃣ app.js (Configuración principal)

javascript
const express = require('express');
const path = require('path');
const productoRoutes = require('./routes/productoRoutes');

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

// ============ CONFIGURACIÓN EJS ============
app.set('view engine', 'ejs');
app.set('views', path.join(__dirname, 'views'));

// ============ MIDDLEWARES ============
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
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'));

// ============ RUTAS ============
app.use('/', productoRoutes);

Comentarios

Entradas más populares de este blog

Cómo Iniciar un Proyecto Node.js

8-Template Engines

6-Middleware?