Servidores web con Express y Node.js

Construcción de un servidor usando el módulo nativo http

Para crear un servidor básico con Node.js, se puede utilizar el módulo http incorporado. A continuación, se muestra un ejemplo en un archivo servidor.js:

const http = require('http');

const host = 'localhost';
const puerto = 3000;

const servidor = http.createServer((solicitud, respuesta) => {
  respuesta.statusCode = 200;
  respuesta.setHeader('Content-Type', 'text/html');
  respuesta.end('Hola Mundo\n');
});

servidor.listen(puerto, () => {
  console.log(`Servidor activo en http://${host}:${puerto}/`);
});

Este enfoque presenta desventajas significativas. Primero, requiere escribir código de bajo nivel, como establecer manualmente códigos de estado HTTP y encabezados, lo que se vuelve complejo al manejar características avanzadas como la autenticación. Segundo, carece de un mecanismo de rutas dedicado; la lógica de enrutamiento debe implementarse dentro de la función de callback, lo que dificulta la escalabilidad en aplicaciones grandes.

Express aborda estas limitaciones mediante dos mejoras clave: objetos de solicitud y respuesta enriquecidos con métodos útiles, y un sistema de rutas flexible que facilita la modularización del código.

Mejoras en los objetos Request y Response

El objeto de solicitud (comúnmente llamado req) incluye propiedades como:

  • req.body: datos del cuerpo de la solicitud, como formularios o JSON.
  • req.params: parámetros de ruta en la URI.
  • req.query: parámetros de consulta en la URI.
  • req.cookies: cookies del cliente.

El objeto de respuesta (res) permite operaciones como enviar HTML, archivos o renderizar plantillas:

// Envío de código HTML
res.send('<h1>Contenido HTML</h1>');

// Envío de un archivo
res.sendFile('documento.pdf');

// Renderización de una plantilla
res.render('pagina');

Sistema de rutas

Las rutas definen cómo el servidor responde a solicitudes en endpoints específicos, combinando una URI y un método HTTP. En Express, se definen con la sintaxis:

aplicacion.METODO(RUTA, CONTROLADOR)

Donde aplicacion es la instancia de Express, METODO es un método HTTP en minúsculas (get, post, etc.), RUTA es la URI, y CONTROLADOR es la función que ejecuta la lógica.

Implementación con Express

Reescribamos el servidor usando Express:

const express = require('express');

const host = 'localhost';
const puerto = 3000;

const aplicacion = express();
aplicacion.get('/', (solicitud, respuesta) => {
  respuesta.send('Hola Mundo');
});

aplicacion.listen(puerto, () => {
  console.log(`Servidor activo en http://${host}:${puerto}/`);
});

Aquí se crea la instancia de Express, se define una ruta para '/' y se inicia el servidor.

Middelwares

Los middlewares son funciones que se ejecutan secuencialmente antes de llegar a la lógica de las rutas. En el flujo simplificado, una solicitud pasa por middlewares en orden, y luego se procesa la ruta correspondiente. Es importante notar que el orden de registro es crucial, y cada middleware debe invocar next() para pasar al siguiente o finalizar la respuesta.

function miMiddleware(solicitud, respuesta, siguiente) {
  // Lógica personalizada
  siguiente();
}

Los middlewares se pueden registrar globalmente o por ruta. Para uso global:

aplicacion.use(miMiddleware);

Para uso en una ruta específica:

aplicacion.get('/ruta-especifica', miMiddleware, (solicitud, respuesta) => {
  respuesta.send('Contenido protegido');
});

Modularización con subrutas

Para aplicaciones grandes, se pueden usar routers de Express para dividir el código. Un router actúa como una mini-aplicación:

const express = require('express');
const enrutador = express.Router();

enrutador.get('/info', (solicitud, respuesta) => {
  respuesta.json({ mensaje: 'Datos de ejemplo' });
});

enrutador.post('/crear', (solicitud, respuesta) => {
  respuesta.status(201).json({ exito: true });
});

Luego, el router se integra en la aplicación principal como middleware:

const aplicacion = express();
aplicacion.use('/api', enrutador);

Esto asigna las rutas del router bajo '/api', por ejemplo, '/api/info' y '/api/crear'. Un ejemplo completo incluiría la creación de un archivo de rutas separado, como routes/datos.js, y su importación en el servidor principle:

// Archivo routes/datos.js
const express = require('express');
const routerDatos = express.Router();

routerDatos.get('/', (solicitud, respuesta) => {
  respuesta.json({ comunidad: 'Ejemplo', sitio: 'https://ejemplo.com' });
});

routerDatos.post('/nuevo', (solicitud, respuesta) => {
  respuesta.status(201).json({ aviso: 'Operación exitosa' });
});

module.exports = routerDatos;

// Archivo servidor.js
const express = require('express');
const routerDatos = require('./routes/datos');

const host = 'localhost';
const puerto = 3000;

const aplicacion = express();
aplicacion.use('/datos', routerDatos);

aplicacion.use('*', (solicitud, respuesta) => {
  respuesta.status(404).send('Página no encontrada');
});

En este caso, las rutas del router están bajo '/datos', y se maneja un error 404 para rutas no definidas.

Etiquetas: express Node.js JavaScript rutas Middleware

Publicado el 6-14 18:54