5-3-API -web

versión completa que incluye ambas interfaces:

  • Interfaz web (HTML dinámico) para visualizar y crear productos desde el navegador.

  • API REST (JSON) para consumir desde clientes externos (Postman, fetch, etc.).

Ambas conviven sin conflictos porque la API usa el prefijo /api.

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

// Middlewares necesarios
app.use(express.json());          // Para leer JSON en las peticiones de la API
app.use(express.urlencoded({ extended: true })); // Para leer formularios web

// Nuestra 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 }
];

// ==========================
// 🌐 INTERFAZ WEB (HTML)
// ==========================

// 1️⃣ WEB - Mostrar todos los productos (lista HTML)
app.get('/', (req, res) => {
  let listaHTML = '';
  for (let p of productos) {
    listaHTML += `
      <li>
        <strong>${p.nombre}</strong> - $${p.precio}
        (<a href="/productos/${p.id}">Ver detalles</a>)
      </li>
    `;
  }

  res.send(`
    <!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>${listaHTML}</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>
      <hr>
      <p><strong>🔗 Endpoints API (JSON):</strong> <a href="/api/productos">/api/productos</a></p>
    </body>
    </html>
  `);
});

// 2️⃣ WEB - Mostrar un solo producto (detalle HTML)
app.get('/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const prod = productos.find(p => p.id === id);
  if (!prod) {
    return res.status(404).send('<h1>404 - Producto no encontrado</h1><a href="/">Volver</a>');
  }
  res.send(`
    <!DOCTYPE html>
    <html>
    <head>
      <title>${prod.nombre}</title>
      <style>body{font-family:Arial;margin:30px;}</style>
    </head>
    <body>
      <h1>📄 Detalle del producto</h1>
      <p><strong>ID:</strong> ${prod.id}</p>
      <p><strong>Nombre:</strong> ${prod.nombre}</p>
      <p><strong>Precio:</strong> $${prod.precio}</p>
      <a href="/">← Volver al listado</a>
    </body>
    </html>
  `);
});

// 3️⃣ WEB - Crear producto (recibe POST del formulario y redirige)
app.post('/productos', (req, res) => {
  const { nombre, precio } = req.body;
  if (!nombre || !precio) {
    return res.send('<h1>Error: faltan datos</h1><a href="/">Volver</a>');
  }
  const nuevoId = productos.length > 0 ? Math.max(...productos.map(p => p.id)) + 1 : 1;
  productos.push({ id: nuevoId, nombre, precio: parseFloat(precio) });
  res.redirect('/'); // Vuelve a la lista actualizada
});

// ==========================
// 🔌 API REST (JSON)
// ==========================

// 1️⃣ API - Obtener todos los productos (JSON)
app.get('/api/productos', (req, res) => {
  res.json(productos);
});

// 2️⃣ API - Obtener un producto por ID (JSON)
app.get('/api/productos/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const prod = productos.find(p => p.id === id);
  if (!prod) {
    return res.status(404).json({ error: 'Producto no encontrado' });
  }
  res.json(prod);
});

// 3️⃣ API - Crear un nuevo producto (JSON)
app.post('/api/productos', (req, res) => {
  const { nombre, precio } = req.body;
  if (!nombre || typeof precio !== 'number') {
    return res.status(400).json({ error: 'Se requiere nombre y precio (número)' });
  }
  const nuevoId = productos.length > 0 ? Math.max(...productos.map(p => p.id)) + 1 : 1;
  const nuevoProducto = { id: nuevoId, nombre, precio };
  productos.push(nuevoProducto);
  res.status(201).json(nuevoProducto);
});

// Iniciar servidor
app.listen(PORT, () => {
  console.log(`✅ Servidor funcionando en http://localhost:${PORT}`);
  console.log('🌐 Interfaz web:');
  console.log('   - Lista de productos: http://localhost:3000/');
  console.log('   - Detalle de producto: http://localhost:3000/productos/1');
  console.log('🔌 API JSON:');
  console.log('   - GET  /api/productos       → Todos los productos');
  console.log('   - GET  /api/productos/:id   → Un producto');
  console.log('   - POST /api/productos       → Crear producto (enviar JSON)');
});

▶️ ¿Cómo lo usan los alumnos?

  1. Guardar como app.js

  2. npm init -y y npm install express

  3. node app.js

  4. Abrir http://localhost:3000 → verán la interfaz web.

  5. Probar los endpoints API con Postman o directamente desde el navegador:

    • http://localhost:3000/api/productos (JSON)

    • http://localhost:3000/api/productos/2 (JSON)

    • Para POST, usar curl o Postman.

✨ Lo que aprenden los alumnos

  • Rutas separadas (web vs API) en un mismo servidor.

  • Generación de HTML dinámico desde el servidor (sin frontend JS).

  • Redirección después de un POST (para evitar reenvío del formulario).

  • Manejo de JSON con express.json().

  • Códigos de estado HTTP (200, 201, 400, 404).

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