8.3-Versión MVC
Versión MVC SIN router (todo integrado en app.js)
Aquí tienes la estructura MVC sin archivos de rutas separados, manteniendo todo en app.js pero organizado por capas:
📁 ESTRUCTURA DEL PROYECTO
mi-app-mvc/ ├── models/ │ └── Producto.js ├── controllers/ │ └── productoController.js ├── views/ │ └── index.ejs ├── public/ │ └── (archivos estáticos) └── app.js
📄 CÓDIGO COMPLETO
1️⃣ models/Producto.js (Modelo - Datos)
// Modelo: Maneja los datos y operaciones class Producto { constructor() { this.productos = [ { id: 1, nombre: 'Laptop', precio: 1000 }, { id: 2, nombre: 'Mouse', precio: 25 }, { id: 3, nombre: 'Teclado', precio: 50 } ]; } // Obtener todos obtenerTodos() { return this.productos; } // Obtener por ID obtenerPorId(id) { return this.productos.find(p => p.id === id); } } module.exports = new Producto();
2️⃣ controllers/productoController.js (Controlador - Lógica)
const Producto = require('../models/Producto'); class ProductoController { // GET /productos - Devolver JSON con todos obtenerTodosJSON(req, res) { const productos = Producto.obtenerTodos(); res.json({ success: true, cantidad: productos.length, productos: productos }); } // GET /productos/:id - Devolver JSON de un producto obtenerUnoJSON(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); } // GET / - Renderizar vista con todos los productos renderizarVista(req, res) { const productos = Producto.obtenerTodos(); res.render('index', { productos }); } } module.exports = new ProductoController();
3️⃣ app.js (Configuración principal SIN router separado)
const express = require('express'); const path = require('path'); const productoController = require('./controllers/productoController'); const app = express(); const PORT = 3000; // ============ CONFIGURAR 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 (usando el controlador) ============ // Rutas API app.get('/productos', productoController.obtenerTodosJSON); app.get('/productos/:id', productoController.obtenerUnoJSON); // Ruta principal (vista) app.get('/', productoController.renderizarVista); // ============ INICIAR SERVIDOR ============ app.listen(PORT, () => { console.log(`=================================`); console.log(`🚀 Servidor MVC corriendo en http://localhost:${PORT}`); console.log(`📦 Ver productos (JSON): http://localhost:${PORT}/productos`); console.log(`🎨 Ver interfaz (EJS): http://localhost:${PORT}`); console.log(`=================================`); });
4️⃣ views/index.ejs (Vista - Interfaz)
<!DOCTYPE html> <html lang="es"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Mi Tienda MVC con EJS</title> <link rel="stylesheet" href="/css/bootstrap.min.css"> </head> <body> <div class="container mt-5"> <h1 class="text-center">📦 Mi Tienda de Productos (MVC)</h1> <div class="row mt-4"> <div class="col-md-6 offset-md-3"> <div class="card"> <div class="card-header"> <h3>Productos disponibles</h3> </div> <div class="card-body"> <ul class="list-group"> <% productos.forEach(producto => { %> <li class="list-group-item"> <strong><%= producto.nombre %></strong> - $<%= producto.precio %> <a href="/productos/<%= producto.id %>" class="btn btn-sm btn-primary float-end">Ver</a> </li> <% }) %> </ul> </div> </div> </div> </div> <!-- Info de arquitectura --> <div class="row mt-4"> <div class="col-md-6 offset-md-3"> <div class="alert alert-info"> <strong>📐 Arquitectura MVC</strong><br> <strong>Modelo:</strong> Producto.js (datos)<br> <strong>Vista:</strong> index.ejs (interfaz)<br> <strong>Controlador:</strong> productoController.js (lógica) </div> </div> </div> </div> <script src="/js/bootstrap.min.js"></script> </body> </html>
📊 COMPARATIVA: CON router vs SIN router
| Versión | Archivos | Complejidad | ¿Cuándo usar? |
|---|---|---|---|
| CON router | models/, controllers/, routes/ | Más compleja | Proyectos grandes (+20 rutas) |
| SIN router | models/, controllers/ | Más simple | Proyectos pequeños/medianos |
🎯 FLUJO DE LA ARQUITECTURA (SIN router)
Petición HTTP
↓
app.js (define rutas)
↓
productoController.js (procesa)
↓
Producto.js (obtiene datos)
↓
productoController.js (formatea respuesta)
↓
Vista EJS o JSON💡 VENTAJAS DE ESTA VERSIÓN SIN ROUTER
Más simple - Un solo archivo de rutas (
app.js)Menos archivos - No necesitas carpeta
routes/Ideal para aprendizaje - Fácil de entender el flujo MVC
Suficiente para proyectos pequeños - Menos de 10-15 rutas
🚀 CÓMO EJECUTAR
# 1. Instalar dependencias npm install express ejs bootstrap # 2. Crear estructura de carpetas mkdir models controllers views public # 3. Crear los archivos con el código anterior # 4. Ejecutar node app.js
📁 ESTRUCTURA FINAL COMPLETA
mi-app-mvc/ ├── models/ │ └── Producto.js ← Datos y lógica de negocio ├── controllers/ │ └── productoController.js ← Procesa peticiones ├── views/ │ └── index.ejs ← Interfaz de usuario ├── public/ ← Archivos estáticos ├── node_modules/ ├── package.json └── app.js ← Configuración y rutas (¡único archivo de rutas!)
¡Así tienes MVC completo SIN archivo de rutas separado
Comentarios
Publicar un comentario