5-6-API -web-router
Vamos a integrar express.Router() en tu ejemplo completo (web + API) manteniendo exactamente la misma funcionalidad, sin CSS adicional y de forma sencilla. La estructura será:
mi-app/
├── app.js
├── routes/
│ ├── webRoutes.js
│ └── apiRoutes.js
├── models/
│ └── productoModel.js
└── package.jsonPaso 1: Crear el modelo (models/productoModel.js)
Centralizamos el arreglo de productos y las operaciones básicas.
// models/productoModel.js
let productos = [
{ id: 1, nombre: 'Laptop', precio: 1000 },
{ id: 2, nombre: 'Mouse', precio: 25 },
{ id: 3, nombre: 'Teclado', precio: 50 }
];
const getAll = () => productos;
const getById = (id) => productos.find(p => p.id === id);
const create = (nombre, precio) => {
const nuevoId = productos.length > 0 ? Math.max(...productos.map(p => p.id)) + 1 : 1;
const nuevoProducto = { id: nuevoId, nombre, precio: parseFloat(precio) };
productos.push(nuevoProducto);
return nuevoProducto;
};
module.exports = { getAll, getById, create };Paso 2: Crear el router para la interfaz web (routes/webRoutes.js)
Aquí van todas las rutas que responden con HTML.
// routes/webRoutes.js
const express = require('express');
const router = express.Router();
const productoModel = require('../models/productoModel');
// WEB: Mostrar todos los productos (lista HTML)
router.get('/', (req, res) => {
const productos = productoModel.getAll();
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>
`);
});
// WEB: Mostrar un solo producto (detalle HTML)
router.get('/productos/:id', (req, res) => {
const id = parseInt(req.params.id);
const prod = productoModel.getById(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>
`);
});
// WEB: Crear producto (recibe POST del formulario y redirige)
router.post('/productos', (req, res) => {
const { nombre, precio } = req.body;
if (!nombre || !precio) {
return res.status(400).send('<h1>Error: faltan datos</h1><a href="/">Volver</a>');
}
productoModel.create(nombre, precio);
res.redirect('/');
});
module.exports = router;Paso 3: Crear el router para la API REST (routes/apiRoutes.js)
Rutas con prefijo /api que devuelven JSON.
// routes/apiRoutes.js
const express = require('express');
const router = express.Router();
const productoModel = require('../models/productoModel');
// API: Obtener todos los productos (JSON)
router.get('/productos', (req, res) => {
const productos = productoModel.getAll();
res.json(productos);
});
// API: Obtener un producto por ID (JSON)
router.get('/productos/:id', (req, res) => {
const id = parseInt(req.params.id);
const prod = productoModel.getById(id);
if (!prod) {
return res.status(404).json({ error: 'Producto no encontrado' });
}
res.json(prod);
});
// API: Crear un nuevo producto (JSON)
router.post('/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 nuevoProducto = productoModel.create(nombre, precio);
res.status(201).json(nuevoProducto);
});
module.exports = router;Paso 4: Archivo principal (app.js) – limpio y usando routers
// app.js
const express = require('express');
const app = express();
const PORT = 3000;
// Middlewares globales
app.use(express.json()); // Para leer JSON (API)
app.use(express.urlencoded({ extended: true })); // Para leer formularios web
// Importar routers
const webRoutes = require('./routes/webRoutes');
const apiRoutes = require('./routes/apiRoutes');
// Montar routers
app.use('/', webRoutes); // Todas las rutas web (HTML) sin prefijo
app.use('/api', apiRoutes); // Todas las rutas API con prefijo /api
// 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 queda la estructura final?
mi-app/
├── app.js
├── models/
│ └── productoModel.js
├── routes/
│ ├── webRoutes.js
│ └── apiRoutes.js
└── package.jsonExplicación del uso de Router para los alumnos
express.Router()crea un mini-manejador de rutas independiente.webRoutescontiene todas las rutas que devuelven HTML (las originales sin/api).apiRoutescontiene las rutas que devuelven JSON, todas bajo el prefijo/api.En
app.jsmontamos cada router conapp.use(prefijo, router). Así las rutas se organizan por responsabilidad y el archivo principal queda muy limpio.El modelo (
productoModel.js) se comparte entre ambos routers, evitando duplicar la lógica de datos.
Beneficios didácticos
Separa claramente la interfaz web de la API REST.
Muestra cómo reutilizar código (el modelo) en diferentes partes de la aplicación.
Prepara a los alumnos para aplicaciones más grandes donde se necesita organización.
No cambia absolutamente nada en el comportamiento original, solo en la estructura del código.
Cómo probarlo
Crear las carpetas y archivos con el contenido exacto de arriba.
Instalar Express:
npm init -y && npm install expressEjecutar:
node app.jsAbrir
http://localhost:3000(web) y también probarhttp://localhost:3000/api/productos(JSON).
Todo funcionará exactamente igual que antes, pero ahora con una arquitectura modular y usando express.Router()
Comentarios
Publicar un comentario