Content is user-generated and unverified.

Instrucciones Completas del Proyecto Web - Node.js + Express + EJS

Índice

  1. Arquitectura del Proyecto
  2. Estructura de Directorios
  3. Conceptos Fundamentales
  4. Configuración Inicial
  5. Implementación Realizada
  6. Explicación Técnica
  7. Próximos Pasos

Arquitectura del Proyecto

Separación Frontend-Backend

Este proyecto utiliza una arquitectura de microservicios simplificada donde:

  • Backend: API REST que maneja la lógica de negocio y datos
  • Frontend: Servidor web que renderiza vistas y consume la API
proyecto-productos/
├── backend/          # API REST (Puerto 3000)
│   ├── package.json
│   └── [tu código existente]
├── frontend/         # Servidor web (Puerto 3001)
│   ├── package.json
│   └── [archivos implementados]
└── instrucciones.md

¿Por qué package.json separados?

1. Separación de Responsabilidades

  • Backend: Necesita dependencias como bases de datos, validadores, middleware de autenticación
  • Frontend: Necesita dependencias como motores de plantillas, clientes HTTP, procesadores de assets

2. Independencia de Despliegue

  • Cada parte puede desplegarse en servidores diferentes
  • Escalabilidad independiente según la demanda
  • Actualizaciones sin afectar la otra parte

3. Gestión de Dependencias

  • Evita conflictos de versiones entre dependencias
  • Tamaño optimizado de node_modules por servicio
  • Facilita el mantenimiento y debugging

4. Ejemplo Práctico

json
// Backend package.json
{
  "dependencies": {
    "express": "^4.18.2",
    "mongoose": "^7.0.0",      // Base de datos
    "bcrypt": "^5.1.0",        // Encriptación
    "jsonwebtoken": "^9.0.0"   // Autenticación
  }
}

// Frontend package.json
{
  "dependencies": {
    "express": "^4.18.2",
    "ejs": "^3.1.9",           // Motor de plantillas
    "axios": "^1.4.0"          // Cliente HTTP
  }
}

Estructura de Directorios

Estructura Actual

proyecto-productos/
├── backend/
│   ├── package.json
│   ├── app.js
│   ├── routes/
│   │   └── productos.js
│   └── models/
│       └── producto.js
├── frontend/
│   ├── package.json
│   ├── app.js
│   ├── routes/
│   │   └── productos.js
│   ├── views/
│   │   ├── productos/
│   │   │   └── lista.ejs
│   │   └── error.ejs
│   └── public/
│       ├── css/
│       │   └── styles.css
│       └── js/
│           └── productos.js
└── instrucciones.md

Conceptos Fundamentales

1. API REST (Backend)

  • Responsabilidad: Manejar datos y lógica de negocio
  • Endpoints: Rutas que responden con JSON
  • Ejemplo: GET /api/productos[{id: 1, nombre: "...", precio: 100}]

2. Servidor Web (Frontend)

  • Responsabilidad: Renderizar HTML y manejar interacción del usuario
  • Proceso: Consume API → Procesa datos → Renderiza EJS → Envía HTML al navegador

3. Flujo de Datos

Navegador → Frontend Server → Backend API → Base de Datos
    ↓              ↓              ↓              ↓
  HTML         EJS Template    JSON          Datos
    ↑              ↑              ↑              ↑
Navegador ← Frontend Server ← Backend API ← Base de Datos

Configuración Inicial

Paso 1: Estructura de Carpetas

bash
# Crear estructura
mkdir frontend
cd frontend
mkdir routes views public
mkdir views/productos public/css public/js

Paso 2: Inicializar Frontend

bash
# En la carpeta frontend
npm init -y
npm install express ejs axios
npm install --save-dev nodemon

Paso 3: Verificar Backend

bash
# En la carpeta backend
# Verificar que existe el endpoint: GET /api/productos
curl http://localhost:3000/api/productos

Implementación Realizada

1. Servidor Principal (frontend/app.js)

javascript
// Configuración del servidor Express
// Motor de plantillas EJS
// Rutas y middleware
// Manejo de errores

2. Router de Productos (frontend/routes/productos.js)

javascript
// Consumo de API con Axios
// Manejo de errores de conexión
// Renderizado de vistas EJS

3. Vista de Lista (frontend/views/productos/lista.ejs)

html
<!-- Tabla responsive con Bootstrap -->
<!-- Manejo de estados (con/sin productos) -->
<!-- Botones de acción preparados -->

4. Estilos y Scripts

css
/* Diseño moderno con animaciones */
/* Responsive design */
/* Efectos hover y transiciones */

Explicación Técnica

¿Por qué Axios y no otra librería?

1. Axios vs Fetch API

javascript
// Axios - Manejo automático de JSON
const response = await axios.get('/api/productos');
const productos = response.data; // Ya es objeto JS

// Fetch - Manejo manual
const response = await fetch('/api/productos');
const productos = await response.json(); // Conversión manual

2. Ventajas de Axios

  • Interceptores: Para manejo global de errores y autenticación
  • Timeout automático: Evita peticiones colgadas
  • Manejo de errores: Distingue entre errores de red y HTTP
  • Compatibilidad: Funciona en Node.js y navegadores
  • Configuración base: URL base, headers comunes

3. Código de Ejemplo

javascript
// Configuración reutilizable
const apiClient = axios.create({
  baseURL: 'http://localhost:3000/api',
  timeout: 5000,
  headers: {
    'Content-Type': 'application/json'
  }
});

// Uso simple
const productos = await apiClient.get('/productos');

Consumo de Endpoints - Flujo Detallado

1. Petición del Usuario

Usuario accede a: http://localhost:3001/productos

2. Router Frontend

javascript
// frontend/routes/productos.js
router.get('/', async (req, res) => {
  try {
    // Paso 3: Petición al backend
    const response = await axios.get('http://localhost:3000/api/productos');
    
    // Paso 4: Procesamiento
    const productos = response.data;
    
    // Paso 5: Renderizado
    res.render('productos/lista', { productos });
  } catch (error) {
    // Manejo de errores
    res.render('error', { error: error.message });
  }
});

3. Backend Response

javascript
// backend/routes/productos.js
router.get('/api/productos', (req, res) => {
  // Lógica de base de datos
  res.json([
    { id: 1, nombre: "Producto 1", precio: 100, unidades: 10 }
  ]);
});

4. Renderizado EJS

html
<!-- frontend/views/productos/lista.ejs -->
<% productos.forEach(producto => { %>
  <tr>
    <td><%= producto.nombre %></td>
    <td>$<%= producto.precio %></td>
    <td><%= producto.unidades %></td>
  </tr>
<% }) %>

Manejo de Errores en el Consumo

1. Errores de Conexión

javascript
try {
  const response = await axios.get('/api/productos');
} catch (error) {
  if (error.code === 'ECONNREFUSED') {
    // Backend no está corriendo
    res.render('error', { 
      error: 'Backend no disponible',
      message: 'Verifica que el servidor backend esté corriendo'
    });
  }
}

2. Errores HTTP

javascript
try {
  const response = await axios.get('/api/productos');
} catch (error) {
  if (error.response?.status === 404) {
    // Endpoint no encontrado
  } else if (error.response?.status === 500) {
    // Error interno del servidor
  }
}

Próximos Pasos

Operaciones CRUD Pendientes

1. Crear Producto

  • Formulario en frontend/views/productos/nuevo.ejs
  • Ruta POST en frontend/routes/productos.js
  • Consumo de POST /api/productos

2. Ver Producto

  • Vista detalle en frontend/views/productos/detalle.ejs
  • Ruta GET con parámetro /:id
  • Consumo de GET /api/productos/:id

3. Editar Producto

  • Formulario pre-llenado en frontend/views/productos/editar.ejs
  • Ruta PUT en frontend
  • Consumo de PUT /api/productos/:id

4. Eliminar Producto

  • Confirmación con JavaScript
  • Petición DELETE desde el frontend
  • Consumo de DELETE /api/productos/:id

Mejoras Adicionales

1. Validación

javascript
// Cliente (JavaScript)
function validarFormulario() {
  // Validaciones del lado del cliente
}

// Servidor (Frontend)
const { body, validationResult } = require('express-validator');
// Validaciones del lado del servidor

2. Notificaciones

javascript
// Sistema de mensajes flash
app.use(session());
app.use(flash());

// Mostrar mensajes de éxito/error
req.flash('success', 'Producto creado exitosamente');

3. Paginación

javascript
// Frontend
const page = req.query.page || 1;
const response = await axios.get(`/api/productos?page=${page}`);

// Backend
const productos = await Producto.find()
  .limit(10)
  .skip((page - 1) * 10);

Comandos Útiles

Desarrollo

bash
# Iniciar backend
cd backend && npm start

# Iniciar frontend (en otra terminal)
cd frontend && npm run dev

# Instalar dependencias
npm install

# Verificar conexión
curl http://localhost:3000/api/productos
curl http://localhost:3001/productos

Debugging

bash
# Logs detallados
DEBUG=express:* npm start

# Verificar puertos
netstat -an | grep 3000
netstat -an | grep 3001

Notas Importantes

  1. Puertos: Backend (3000), Frontend (3001)
  2. URLs: Ajustar API_BASE_URL en frontend/routes/productos.js
  3. CORS: Si hay problemas, configurar CORS en el backend
  4. Datos: El frontend espera estructura específica del backend
  5. Errores: Siempre manejar errores de conexión y HTTP

Documento actualizado: Primera implementación - Operación LISTAR productos

Content is user-generated and unverified.
    Instrucciones Completas del Proyecto - instrucciones.md | Claude