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

text
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)

javascript
// 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)

javascript
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)

javascript
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)

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 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ónArchivosComplejidad¿Cuándo usar?
CON routermodels/, controllers/, routes/Más complejaProyectos grandes (+20 rutas)
SIN routermodels/, controllers/Más simpleProyectos pequeños/medianos

🎯 FLUJO DE LA ARQUITECTURA (SIN router)

text
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

  1. Más simple - Un solo archivo de rutas (app.js)

  2. Menos archivos - No necesitas carpeta routes/

  3. Ideal para aprendizaje - Fácil de entender el flujo MVC

  4. Suficiente para proyectos pequeños - Menos de 10-15 rutas

🚀 CÓMO EJECUTAR

bash
# 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

text
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

Entradas más populares de este blog

Cómo Iniciar un Proyecto Node.js

8-Template Engines

6-Middleware?