Volver a la lista

Creación de un servidor de datos de experimentos con Express.

Aprenda a crear un servidor de API de datos de experimentos con Express.js. Aprenda sobre enrutamiento, middleware y API REST a través de ejemplos de biología.

Principiante
|
60min
|
Verificado (2026-06)
ExpressNode.jsServidorEnrutamientoMiddlewareREST API
Progreso0/19 (0%)

Crear un servidor de datos de experimentos con Express

Hasta ahora, hemos aprendido a solicitar datos a un servidor con fetch. Ahora, vamos a crear el lado opuesto: un servidor que envíe datos.

Al igual que en un laboratorio se utiliza un LIMS (Sistema de Gestión de Información de Laboratorio), en la web necesitamos un servidor que almacene y proporcione datos. Express es la herramienta para crear ese servidor. Es un framework web que se ejecuta sobre Node.js, que hemos aprendido antes: en otras palabras, es un kit de herramientas para el desarrollo de servidores.

Aunque se puede crear un servidor solo con Node.js (¿recuerdas http.createServer?), tendríamos que implementar todo manualmente. Con Express, el framework se encarga de tareas repetitivas, como enviar diferentes datos según la URL, proporcionar archivos o gestionar errores. Es como utilizar un kit validado en lugar de comprar y combinar los reactivos uno por uno.

Hola Mundo: Empezar un servidor en 3 líneas

Esta es la forma más básica de un servidor Express:

javascript
const express = require("express");
const app = express();

app.get("/", function(req, res) {
  res.send("LIMS Server Running");
});

app.listen(3000, function() {
  console.log("Servidor iniciado: http://localhost:3000");
});

Guarde este código como server.js y ejecute node server.js en la terminal, y podrá acceder a él en el navegador a través de http://localhost:3000.

Desglosemos los elementos clave:

  • require("express") — Importa la biblioteca Express.
  • app.get("/", ...) — Registra una función que se ejecutará cuando se acceda a la ruta "/".
  • req — Solicitud (request). Información enviada por el cliente.
  • res — Respuesta (response). Información que el servidor enviará.
  • res.send() — Envía datos al cliente.
  • app.listen(3000) — Escucha las solicitudes en el puerto 3000.

Enrutamiento: enviar diferentes datos según la URL

El enrutamiento (routing) consiste en determinar "qué datos se enviarán cuando se realice una solicitud a una determinada dirección". En LIMS, es como ingresar un número de muestra para obtener la información correspondiente, o ingresar el nombre de un protocolo para obtener el protocolo correspondiente.

javascript
const express = require("express");
const app = express();

app.get("/", function(req, res) {
  res.send("Bienvenido al servidor de datos experimentales");
});

app.get("/genes", function(req, res) {
  const genes = [
    { name: "TP53", chromosome: "17p13.1", type: "tumor suppressor" },
    { name: "BRCA1", chromosome: "17q21.31", type: "DNA repair" },
    { name: "EGFR", chromosome: "7p11.2", type: "receptor tyrosine kinase" }
  ];
  res.json(genes);
});

app.get("/protocols", function(req, res) {
  const protocols = ["DNA Extraction", "PCR", "Western Blot", "ELISA"];
  res.json(protocols);
});

app.listen(3000, function() {
  console.log("Servidor iniciado: http://localhost:3000");
});

Al acceder a http://localhost:3000/genes, se muestra una lista de genes en formato JSON, y al acceder a /protocols, se muestra una lista de protocolos en formato JSON. res.json() convierte un objeto JavaScript en formato JSON y lo envía.

Enrutamiento dinámico: recibir parámetros desde la URL

Si desea consultar solo la información de un gen específico, incluya un parámetro en la URL:

javascript
const geneDatabase = {
  TP53: { name: "TP53", chromosome: "17p13.1", function: "tumor suppressor", length_bp: 19149 },
  BRCA1: { name: "BRCA1", chromosome: "17q21.31", function: "DNA repair", length_bp: 81189 },
  EGFR: { name: "EGFR", chromosome: "7p11.2", function: "receptor tyrosine kinase", length_bp: 188307 }
};

app.get("/gene/:id", function(req, res) {
  const geneId = req.params.id;
  const gene = geneDatabase[geneId];

  if (gene) {
    res.json(gene);
  } else {
    res.status(404).json({ error: "No se encontró el gen solicitado", query: geneId });
  }
});

Al acceder a /gene/TP53 se obtiene la información de TP53, y al acceder a /gene/XYZ123 se devuelve un error 404. La parte :id es un parámetro de la URL; este cambia cada vez que se realiza una solicitud y se extrae con req.params.id.

Middleware: etapa de preprocesamiento experimental

El middleware es un concepto clave de Express. Es la etapa de procesamiento que se realiza entre el momento en que una solicitud llega al servidor y el momento en que se envía una respuesta.

Piense en el proceso de preprocesamiento que se realiza en un experimento antes de que una muestra entre en el equipo de análisis:

text
[Recepción de la muestra] → [Verificación de la etiqueta] → [Control de calidad] → [Preprocesamiento] → [Análisis] → [Informe de resultados]

En Express, las solicitudes también siguen el mismo flujo de trabajo:

text
[Llega la solicitud] → [Middleware 1] → [Middleware 2] → [Controlador de ruta] → [Envío de la respuesta]

El middleware se registra como app.use():

javascript
const express = require("express");
const app = express();

app.use(function(req, res, next) {
  console.log(`[${new Date().toISOString()}] ${req.method} ${req.url}`);
  next();
});

app.get("/genes", function(req, res) {
  res.json([{ name: "TP53" }, { name: "BRCA1" }]);
});

app.listen(3000);

La función registrada con app.use() se ejecuta para cada solicitud. Aquí, cada vez que llega una solicitud, se registra la hora, el método (GET/POST) y la dirección en la consola. Es como escribir en un cuaderno de laboratorio: "A qué hora, qué muestra y qué análisis se realizó".

Lo importante es next(). Esta función debe llamarse para pasar a la siguiente etapa (el siguiente middleware o controlador de ruta). Si no se llama a next(), la solicitud se detiene aquí y no se envía ninguna respuesta, al igual que una muestra que no pasa el control de calidad no pasa a la siguiente etapa.

Middleware práctico: análisis de datos POST

Si el cliente envía datos mediante el método POST (por ejemplo, para registrar una nueva muestra), es necesario analizarlos para que se puedan leer. Express proporciona un middleware integrado para ello:

javascript
app.use(express.json());

app.post("/samples", function(req, res) {
  const newSample = req.body;
  console.log("Nueva muestra registrada:", newSample);
  res.json({ message: "Muestra registrada correctamente", sample: newSample });
});

Si no hay express.json(), entonces req.body es undefined. Este middleware analiza automáticamente los datos que llegan en formato JSON y los introduce en req.body.

Ejemplo completo: API de gestión de muestras

Vamos a crear un servidor de gestión de muestras sencillo combinando lo que hemos aprendido hasta ahora:

javascript
const express = require("express");
const app = express();

app.use(express.json());

app.use(function(req, res, next) {
  console.log(`[LOG] ${req.method} ${req.url}`);
  next();
});

const samples = [
  { id: "S001", name: "Blood Sample A", od: 1.85, status: "pass" },
  { id: "S002", name: "Tissue Sample B", od: 0.42, status: "fail" },
  { id: "S003", name: "Serum Sample C", od: 2.10, status: "pass" }
];

app.get("/samples", function(req, res) {
  res.json(samples);
});

app.get("/sample/:id", function(req, res) {
  const found = samples.find(function(s) {
    return s.id === req.params.id;
  });

  if (found) {
    res.json(found);
  } else {
    res.status(404).json({ error: "No se encontró la muestra" });
  }
});

app.get("/samples/passed", function(req, res) {
  const passed = samples.filter(function(s) {
    return s.status === "pass";
  });
  res.json({ count: passed.length, samples: passed });
});

app.listen(3000, function() {
  console.log("Servidor de gestión de muestras iniciado: http://localhost:3000");
});

Este servidor ofrece tres puntos finales de API:

  • GET /samples — Lista completa de muestras
  • GET /sample/S001 — Consulta de una muestra específica
  • GET /samples/passed — Filtrado para mostrar solo las muestras que pasaron el control de calidad

Si realiza una solicitud a este servidor utilizando fetch, que aprendimos anteriormente:

javascript
fetch("http://localhost:3000/samples/passed")
  .then(function(response) { return response.json(); })
  .then(function(data) { console.log(data); });
// { count: 2, samples: [{ id: "S001", ... }, { id: "S003", ... }] }

El siguiente es el momento en que el frontend (fetch) y el backend (Express) se conectan. Es una versión simplificada de lo que sucede cuando se busca un gen en NCBI.

¡Pruébalo tú mismo! (Ejemplo atenuado)

Completa los espacios en blanco a continuación para completar la ruta de Express que devuelve la información del gen.

Completar espaciosjavascript
const express = require("express");
const app = express();
app.get("/gene/", function(req, res) {
const geneId = req..id;
res.json({ gene: geneId, found: true });
});
app.listen();

Errores comunes y soluciones

P: Obtengo un error Cannot GET /ruta

La ruta para ese endpoint no ha sido registrada. Verifique si existe el código app.get("/ruta", ...) y que no haya errores tipográficos. Si no hay una ruta registrada, Express envía automáticamente el mensaje Cannot GET.

P: req.body es undefined

Asegúrese de que app.use(express.json()) esté declarado antes de la ruta. El middleware se ejecuta en el orden del código. Si el middleware de parsing de JSON se encuentra después de la ruta, la solicitud llegará a la ruta sin haber sido procesada aún.

P: Modifiqué el servidor pero los cambios no se reflejan

Node.js no aplica los cambios automáticamente al modificar el código. Detenga el servidor en la terminal con Ctrl+C y ejecútelo de nuevo con node server.js. Si necesita reinicio automático, instale nodemon y ejecútelo con nodemon server.js.

P: Error: listen EADDRINUSE: address already in use :::3000

Ya hay un programa utilizando el puerto 3000. Es posible que un servidor ejecutado anteriormente aún esté activo. Verifique con lsof -i :3000 y finalícelo, o cambie el número de puerto a 3001, por ejemplo.

P: Dicen que Express es un "framework", ¿en qué se diferencia de otros paquetes que se instalan con npm (como mysql2, etc.)?

La diferencia clave es quién llama a quién. mysql2 es una librería: usted llama a connection.query() cuando lo necesita. Express es un framework: si registra código como app.get("/ruta", callback), cuando llegue una solicitud, Express llamará a su callback.

Este concepto se denomina "Inversión de Control (Inversion of Control)". Para una analogía y explicación más detalladas, consulte el tema Framework y Librería.

💬 Preguntas y comentarios

0 comentarios

Puedes publicar sin iniciar sesión. Los comentarios de invitados no pueden editarse ni eliminarse después.

0/2000

Cargando...