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.
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?
Guardar como
app.jsnpm init -yynpm install expressnode app.jsAbrir
http://localhost:3000→ verán la interfaz web.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
curlo 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
Publicar un comentario