10-1-Rutas
Regla de oro:
Usa router cuando: El proyecto crece y tienes múltiples "módulos" o "entidades"
NO uses router cuando: Proyecto pequeño, pocas rutas, un solo objeto
Cómo Manejar Rutas Web en Node.js para una Aplicación Web
Si estás desarrollando una aplicación web tradicional (no solo una API), el manejo de rutas es clave para la navegación, renderizado de vistas y flujo de usuarios. En este post, aprenderás a estructurar rutas en Express.js para crear una aplicación web completa.
📌 ¿Qué Incluiremos?
✅ Rutas básicas para páginas web
✅ Renderizado de vistas con motores como EJS/Pug
✅ Rutas protegidas (autenticación)
✅ Manejo de formularios (POST)
✅ Errores 404 y redirecciones
1. Estructura Básica de una App Web con Express
Primero, instala Express y un motor de plantillas (usaremos EJS):
npm install express ejsCrea un servidor básico con rutas para páginas:
const express = require('express');
const app = express();
const PORT = 3000;
// Configurar EJS como motor de plantillas
app.set('view engine', 'ejs');
app.set('views', './views'); // Carpeta donde están las vistas
// Ruta para la página de inicio
app.get('/', (req, res) => {
res.render('home', { title: 'Inicio' }); // Renderiza views/home.ejs
});
// Ruta para la página "Acerca de"
app.get('/about', (req, res) => {
res.render('about', { title: 'Acerca de' });
});
app.listen(PORT, () => {
console.log(`Servidor web en http://localhost:${PORT}`);
});📂 Estructura de archivos:
/proyecto
/views
home.ejs
about.ejs
app.jsEjemplo de home.ejs:
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
</head>
<body>
<h1>Bienvenido a <%= title %></h1>
<a href="/about">Ir a About</a>
</body>
</html>2. Rutas con Parámetros (Ej: Perfiles de Usuario)
Para páginas dinámicas (como un perfil de usuario):
// Ruta con parámetro :username
app.get('/user/:username', (req, res) => {
const user = {
name: req.params.username,
role: 'Admin'
};
res.render('profile', { user });
});📌 Uso en profile.ejs:
<h2>Perfil de <%= user.name %></h2>
<p>Rol: <%= user.role %></p>3. Rutas Protegidas (Middleware de Autenticación)
Ejemplo de ruta solo para usuarios logueados:
// Middleware de autenticación
function checkAuth(req, res, next) {
const isLoggedIn = true; // En un caso real, verificaría con sesiones/JWT
if (isLoggedIn) {
next(); // Usuario autenticado, continuar
} else {
res.redirect('/login'); // Redirigir al login
}
}
// Ruta protegida (dashboard)
app.get('/dashboard', checkAuth, (req, res) => {
res.render('dashboard');
});4. Manejo de Formularios (POST)
Para procesar datos de formularios (necesitarás express.urlencoded):
app.use(express.urlencoded({ extended: true })); // Parsear datos de formularios
// Ruta para mostrar el formulario
app.get('/contact', (req, res) => {
res.render('contact');
});
// Ruta para procesar el formulario
app.post('/contact', (req, res) => {
const { name, email } = req.body;
console.log(`Datos recibidos: ${name}, ${email}`);
res.redirect('/thank-you');
});
// Página de agradecimiento
app.get('/thank-you', (req, res) => {
res.render('thank-you');
});📌 Ejemplo de contact.ejs:
<form action="/contact" method="POST">
<input type="text" name="name" placeholder="Nombre">
<input type="email" name="email" placeholder="Email">
<button type="submit">Enviar</button>
</form>5. Manejo de Errores (404 y Redirecciones)
🔹 Página 404 (Ruta no encontrada)
app.use((req, res) => {
res.status(404).render('404', { title: 'Página no encontrada' });
});🔹 Redirecciones
app.get('/old-page', (req, res) => {
res.redirect(301, '/new-page'); // Redirección permanente
});6. Organización Avanzada con express.Router()
Para escalar la aplicación, separa las rutas en archivos:
routes/auth.js
const express = require('express');
const router = express.Router();
router.get('/login', (req, res) => {
res.render('login');
});
router.post('/login', (req, res) => {
// Lógica de autenticación
res.redirect('/dashboard');
});
module.exports = router;En app.js:
const authRoutes = require('./routes/auth');
app.use('/auth', authRoutes); // Todas las rutas empiezan con /auth🚀 Conclusión
Con Express.js, puedes construir aplicaciones web robustas manejando:
✔ Renderizado de vistas (EJS, Pug, Handlebars).
✔ Rutas dinámicas (parámetros en URLs).
✔ Autenticación y protección de rutas.
✔ Formularios y redirecciones.
✔ Estructura modular con Router.
Diferencia entre app.get() y app.use() en Express.js
Cuando trabajamos con Express.js, dos métodos fundamentales para manejar rutas y middleware son app.get() y app.use(). Aunque ambos se usan para gestionar solicitudes, tienen propósitos distintos. Vamos a explicarlos con ejemplos prácticos.
1. app.get(): Manejo de rutas específicas (GET)
Este método se utiliza para definir rutas que responden solo a solicitudes HTTP GET en un path específico.
Ejemplo: Respuesta con un string
const express = require('express');
const app = express();
const port = 3000;
app.get('/', (req, res) => {
res.send('Mi respuesta desde Express');
});
app.listen(port, () => {
console.log('Servidor en puerto', port);
});Si accedes a
http://localhost:3000/, Express responderá con el mensaje definido.No funcionará para POST, PUT u otros métodos HTTP.
2. app.use(): Middleware y archivos estáticos
Este método se usa para:
Middleware: Funciones que se ejecutan en cada solicitud (ej:
express.json()).Servir archivos estáticos: Como HTML, CSS, JS, imágenes, etc.
Ejemplo: Configurar carpeta public/
Estructura de proyecto:
mi-app/
├── public/
│ ├── css/style.css
│ ├── js/app.js
│ ├── 404.html
│ └── index.htmlapp.use(express.static(__dirname + "/public"));Acceso directo: Los archivos en
public/se sirven directamente.http://localhost:3000/404.html→ muestra404.html.http://localhost:3000/css/style.css→ sirve el archivo CSS.
¿Qué pasa si hay un index.html?
Si existe public/index.html y el middleware express.static está antes de app.get('/'), Express priorizará el archivo estático:
app.use(express.static(__dirname + "/public")); // Se ejecuta primero
app.get('/', (req, res) => {
res.send('Este mensaje NO se verá'); // ¡No se ejecuta!
});Al visitar
http://localhost:3000/, se mostraráindex.htmlen lugar del mensaje deapp.get().
Diferencias clave
app.get() | app.use() |
|---|---|
| Solo maneja solicitudes GET. | Maneja todas las solicitudes (GET, POST, etc.). |
Se usa para rutas específicas (/, /users). | Se usa para middleware o archivos estáticos. |
| Más restrictivo. | Más flexible (ejecuta en todas las rutas a menos que se limite). |
Conclusión
Usa
app.get()para rutas específicas con el método GET.Usa
app.use()para middleware o servir archivos estáticos.El orden de declaración importa: si
express.staticestá antes queapp.get('/'), Express priorizará los archivos estáticos.
¡Experimenta con estos ejemplos y refuerza tu entendimiento de Express!
Ejemplo 2: Rutas modularizadas
Si tienes rutas definidas en otro archivo (ej: RutasWeb.js), puedes usarlas con app.use():
// Importar y usar rutas externas
app.use('/', require('./router/RutasWeb'));Ventaja: Organiza mejor el código.
Comportamiento: Todas las rutas definidas en
RutasWeb.jsse montan bajo/.
Diferencias clave
app.get() | app.use() |
|---|---|
| Solo maneja solicitudes GET. | Maneja todas las solicitudes (GET, POST, etc.). |
Para rutas específicas (/, /users). | Para middleware, archivos estáticos o rutas modularizadas. |
| Más restrictivo. | Más flexible (se ejecuta en todas las rutas a menos que se limite). |
Conclusión
Usa
app.get()para rutas específicas con el método GET.Usa
app.use()para:Middleware (ej:
express.json()).Archivos estáticos (
express.static).Rutas modularizadas (ej:
app.use('/', require('./router/RutasWeb'))).
¡El orden importa! Si express.static o un middleware está antes que app.get('/'), Express priorizará lo declarado primero.
Bonus: Ejemplo de RutasWeb.js
Para que funcione app.use('/', require('./router/RutasWeb')), el archivo RutasWeb.js debe exportar un router de Express:
// router/RutasWeb.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.send('Ruta principal desde RutasWeb');
});
router.get('/about', (req, res) => {
res.send('Acerca de nosotros');
});
module.exports = router;¡Espero que esta ampliación te sea útil
*******************************************************
Estructura de archivos propuesta:
mi-proyecto/
├── app.js
├── routes/
│ ├── productos.js
│ └── index.js
├── public/
│ └── index.html
└── node_modules/1. Archivo routes/productos.js (todas las rutas de productos)
const express = require('express');
const router = express.Router();
// Datos (en un proyecto real, esto vendría de una base de datos)
let productos = [
{ id: 1, nombre: "Laptop", precio: 999.99 },
{ id: 2, nombre: "Mouse", precio: 19.99 }
];
// ✅ Todas las rutas de productos van aquí
// Rutas agrupadas con route()
router.route('/')
.get((req, res) => {
res.json({
success: true,
cantidad: productos.length,
productos: productos
});
})
.post((req, res) => {
const { nombre, precio } = req.body;
if (!nombre || !precio) {
return res.status(400).json({ error: 'Faltan datos: nombre y precio' });
}
const nuevoProducto = {
id: productos.length + 1,
nombre: nombre,
precio: parseFloat(precio)
};
productos.push(nuevoProducto);
res.status(201).json({
mensaje: '✅ Producto creado',
producto: nuevoProducto
});
});
// Ruta específica con parámetro
router.get('/:id', (req, res) => {
const id = parseInt(req.params.id);
const producto = productos.find(p => p.id === id);
if (!producto) {
return res.status(404).json({ error: 'Producto no encontrado' });
}
res.json(producto);
});
// Ruta para formulario (HTML)
router.post('/formulario', (req, res) => {
const { nombre, precio } = req.body;
if (!nombre || !precio) {
return res.status(400).send('<h1>Error</h1><p>Faltan datos</p><a href="/">Volver</a>');
}
const nuevoProducto = {
id: productos.length + 1,
nombre: nombre,
precio: parseFloat(precio)
};
productos.push(nuevoProducto);
res.redirect('/');
});
module.exports = router;2. Archivo app.js (principal - MUCHO más limpio)
const express = require('express');
const app = express();
const PORT = 3000;
// Importar rutas
const productosRoutes = require('./routes/productos');
// Middlewares globales
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'));
// 📍 USAR LAS RUTAS - aquí se monta el router
app.use('/productos', productosRoutes);
// Ruta principal (puede ir aquí o en un router separado)
app.get('/', (req, res) => {
res.sendFile(__dirname + '/public/index.html');
});
app.listen(PORT, () => {
console.log(`🚀 Servidor en http://localhost:${PORT}`);
});3. Opcional: Archivo routes/index.js (para centralizar aún más)
const express = require('express');
const router = express.Router();
const productosRoutes = require('./productos');
// Ruta principal
router.get('/', (req, res) => {
res.sendFile(__dirname + '/../public/index.html');
});
// Montar otras rutas
router.use('/productos', productosRoutes);
module.exports = router;Y luego en app.js solo tendrías:
const indexRoutes = require('./routes/index');
app.use('/', indexRoutes);
Comentarios
Publicar un comentario