Lección 4 de 912 min
Arquitecturas web modernas
Jamstack, MACH, headless, edge computing, offline-first y local-first.
Una revista digital publica en su web, en su app móvil y en las pantallas de varios quioscos. Muchos de sus lectores leen en el metro, sin cobertura, y el equipo de redacción quiere cambiar un titular sin pedir un despliegue. Ninguna de esas necesidades encaja bien con el modelo clásico de un servidor que genera cada página en un único centro de datos.
Las arquitecturas de esta lección mueven las piezas de sitio: separan el contenido de su presentación, llevan el código a servidores cercanos al usuario o incluso dejan los datos en su propio dispositivo.
Separar la presentación del resto
Jamstack
Páginas generadas de antemano, servidas desde una CDN y enriquecidas con APIs.
- Siglas:
- JavaScript, APIs, Markup
- Se sirve desde:
- Una CDN
Jamstack (originalmente JAM: JavaScript, APIs y Markup) propone generar el HTML al construir el sitio, publicarlo como archivos estáticos en una CDN (una red de servidores repartidos por el mundo) y añadir lo dinámico con JavaScript que llama a APIs: búsquedas, formularios, pagos.
Como ningún servidor genera las páginas en cada visita, el sitio es rápido, barato de alojar y ofrece muy poca superficie de ataque. Cuando cambia el contenido, un webhook (un aviso automático por HTTP) lanza un build nuevo.
Úsalo cuando
Para blogs, documentación, webs corporativas y tiendas con un catálogo que cambia pocas veces al día.
Ten en cuenta
Con miles de páginas los builds se vuelven lentos, y el contenido que cambia cada minuto no encaja. El término ha perdido protagonismo: muchas de sus ideas se integraron en frameworks que mezclan páginas estáticas y dinámicas, como verás en la lección de estrategias de renderizado.
// 1. Pide el contenido una sola vez, al construir el sitio
const articulos: Articulo[] = await fetch("https://cms.ejemplo.com/api/articulos")
.then((r) => r.json());
// 2. Genera un archivo HTML por artículo
for (const articulo of articulos) {
await writeFile(`dist/${articulo.slug}.html`, plantilla(articulo));
}
// 3. La carpeta dist/ se sube a la CDN. Si el CMS cambia algo,
// un webhook vuelve a lanzar este script.Arquitectura headless
Un backend sin interfaz propia que entrega contenido o comercio por API.
- CMS headless:
- Strapi, Contentful, Sanity
Un CMS tradicional, como WordPress en su uso clásico, gestiona el contenido y además genera las páginas: el «cuerpo» y la «cabeza» van unidos. Un sistema headless («sin cabeza») se queda solo con el cuerpo: guarda y gestiona el contenido y lo entrega por una API, REST o GraphQL. Cada frontend, sea la web, la app o la pantalla del quiosco, decide cómo mostrarlo.
La idea se aplica igual al comercio electrónico: un headless commerce gestiona catálogo, precios, carritos y pedidos por API, mientras el equipo de frontend construye la tienda con el framework que prefiera.
Úsalo cuando
Cuando el mismo contenido se publica en varios canales, o cuando el equipo de frontend necesita libertad total de diseño y de tecnología.
Ten en cuenta
Pierdes lo que el sistema tradicional daba hecho: vista previa, plantillas, SEO básico. Ahora hay que construirlo. Y tu web depende de que la API del proveedor responda.
// El CMS solo entrega datos; cada canal los presenta a su manera
const respuesta = await fetch("https://cms.ejemplo.com/api/articulos/gazpacho", {
headers: { Authorization: `Bearer ${process.env.CMS_TOKEN}` },
});
const articulo: { titulo: string; cuerpo: string; imagen: string } =
await respuesta.json();
// La web lo convierte en HTML, la app en una vista nativa
// y el quiosco en una diapositiva. El contenido es el mismo.MACH
Microservicios, API-first, Cloud-native y Headless: piezas componibles.
- Lo promueve:
- MACH Alliance
MACH es un acrónimo que reúne cuatro principios: Microservicios (cada capacidad es un servicio independiente), API-first (todo se diseña primero como API), Cloud-native (se ejecuta en la nube como servicio gestionado que escala solo) y Headless (la interfaz va separada del backend).
En la práctica describe una forma de montar plataformas de comercio y contenido componibles: en lugar de una suite que lo hace todo, eliges un proveedor especializado para cada pieza (buscador, pagos, CMS, catálogo) y las unes por API. Si un proveedor deja de convencerte, cambias solo esa pieza. Lo promueve la MACH Alliance, una asociación de empresas del sector.
Úsalo cuando
En empresas medianas y grandes, sobre todo de comercio electrónico, que quieren combinar proveedores especializados y sustituirlos sin rehacer toda la plataforma.
Ten en cuenta
Componer diez proveedores significa diez contratos, diez facturas y diez APIs que integrar y vigilar. Para una tienda pequeña, una plataforma todo en uno suele ser más sensata.
// Cada pieza de la tienda es un proveedor distinto, unido por API
const [resultados, precio, banner] = await Promise.all([
buscador.buscar("zapatillas"), // servicio de búsqueda
comercio.precio("SKU-123"), // motor de comercio headless
cms.obtener("banner-rebajas"), // CMS headless
]);
// Cambiar de buscador solo afecta a la primera piezaNota
Las tres ideas se solapan: un sitio Jamstack suele leer su contenido de un CMS headless, y headless es la H de MACH. Lo que cambia es la escala: de una web estática a toda una plataforma de proveedores.
Acercar el código y los datos al usuario
Edge computing
Ejecutar código en servidores repartidos por el mundo, cerca de quien pide.
- Ejemplos:
- Cloudflare Workers, Deno Deploy
Una CDN ya sirve archivos estáticos desde muchas ubicaciones. El edge computing da un paso más: ejecuta tu código en esos mismos puntos, cerca del usuario. Una petición desde Buenos Aires la atiende un servidor próximo, no uno al otro lado del océano.
Las plataformas de edge, como Cloudflare Workers o Deno Deploy, suelen ejecutar funciones ligeras con APIs web estándar (Request, Response, fetch) que arrancan muy rápido. Son ideales para lógica pequeña antes de llegar al servidor de origen: redirigir por país, comprobar una cookie de sesión, elegir la variante de un test A/B o reescribir cabeceras.
Úsalo cuando
Para personalización y decisiones rápidas que no necesitan la base de datos central, y para reducir la latencia a usuarios de todo el mundo.
Ten en cuenta
Si el código del edge tiene que consultar una base de datos que está en un solo país, pierdes la ventaja: cada petición viaja igualmente hasta allí. Además, estos entornos suelen limitar la CPU y no ofrecen todas las APIs de Node.js.
export default {
async fetch(peticion: Request): Promise<Response> {
// Cloudflare indica el país del visitante en una cabecera
const pais = peticion.headers.get("cf-ipcountry");
const url = new URL(peticion.url);
if (pais === "MX" && !url.pathname.startsWith("/mx")) {
return Response.redirect(`${url.origin}/mx${url.pathname}`, 302);
}
return fetch(peticion); // el resto sigue hacia el servidor de origen
},
};Offline-first
Diseñar la app para que funcione sin red y se sincronice al volver la conexión.
- Piezas:
- Service Worker, IndexedDB, Cache API
Una app offline-first trata la falta de conexión como una situación normal, no como un error. La interfaz y los datos recientes se guardan en el dispositivo, así que la app abre y responde aunque estés en un túnel. Los cambios que haces sin red se guardan en una cola local y se envían al servidor cuando vuelve la conexión.
En la web, la pieza clave es el Service Worker: un script que el navegador ejecuta aparte de la página y que intercepta sus peticiones, de modo que puede responder desde una caché local. Los datos se guardan en IndexedDB o en la Cache API. Así funcionan las PWA (Progressive Web Apps).
Úsalo cuando
En apps que se usan en movilidad o con mala cobertura: trabajo de campo, transporte, inventario en almacenes, lectura de contenidos.
Ten en cuenta
Lo difícil es sincronizar: ¿qué pasa si dos personas cambian lo mismo sin conexión? Necesitas una política para los conflictos. Y el servidor sigue siendo la fuente de verdad: lo local es una copia que puede quedarse vieja.
// sw.ts (Service Worker): primero la caché; si no está, la red
self.addEventListener("fetch", (evento: FetchEvent) => {
evento.respondWith(
caches.match(evento.request).then((guardada) => guardada ?? fetch(evento.request)),
);
});
// app.ts: al recuperar la conexión, envía los cambios pendientes
window.addEventListener("online", async () => {
for (const cambio of await colaLocal.pendientes()) {
await fetch("/api/cambios", { method: "POST", body: JSON.stringify(cambio) });
await colaLocal.marcarEnviado(cambio.id);
}
});Local-first
Los datos viven en tu dispositivo; la nube solo ayuda a sincronizar y colaborar.
- Pieza clave:
- CRDT
- Bibliotecas:
- Yjs, Automerge
Local-first va más allá de offline-first: la copia principal de los datos está en el dispositivo del usuario, no en el servidor. La app lee y escribe siempre en local, así que todo es instantáneo y funciona sin red; el servidor, si existe, solo reparte los cambios entre dispositivos y personas. El término lo popularizó un ensayo del laboratorio Ink & Switch publicado en 2019.
Para que varias personas editen lo mismo a la vez sin un servidor que arbitre se usan CRDT (Conflict-free Replicated Data Types): estructuras de datos diseñadas para que, al combinar cambios hechos en paralelo, todas las copias acaben en el mismo estado, lleguen en el orden que lleguen. Bibliotecas como Yjs o Automerge las implementan.
Úsalo cuando
En herramientas de creación y colaboración (notas, documentos, diseño, listas compartidas) donde la rapidez, el trabajo sin conexión y la propiedad de los datos importan.
Ten en cuenta
Es un campo todavía joven. Los CRDT garantizan que las copias coincidan, no que el resultado tenga sentido para el negocio: no sirven para un saldo bancario ni para vender la última plaza de un vuelo. Y cambiar el formato de unos datos repartidos por miles de dispositivos es difícil.
import * as Y from "yjs";
const doc = new Y.Doc();
const lista = doc.getArray<string>("compra");
lista.push(["pan", "tomates"]); // se escribe en local, al instante
// Cada cambio produce una actualización que se envía a los demás
doc.on("update", (actualizacion: Uint8Array) => enviarAPares(actualizacion));
// Al recibir la de otra persona, se fusiona sin conflictos
recibirDePares((actualizacion) => Y.applyUpdate(doc, actualizacion));Offline-first frente a local-first
En offline-first, el servidor es la fuente de verdad y el dispositivo guarda una copia para aguantar sin red. En local-first, la fuente de verdad es el dispositivo y el servidor es un ayudante que sincroniza. El edge computing va por otro camino: acerca el servidor al usuario, pero sigue haciendo falta conexión.
Interactivo
¿Dónde se ejecuta el código y dónde viven los datos?
Compara el modelo clásico con las tres formas de acercarse al usuario.
| Característica | Servidor central | Edge computing | Offline-first |
|---|---|---|---|
| Dónde se ejecuta la lógica | En un centro de datos | En servidores cercanos al usuario | En el dispositivo y en el servidor |
| Fuente de verdad | La base de datos del servidor | Normalmente, una base de datos central | El servidor; el dispositivo guarda una copia |
| Sin conexión | No funciona | No funciona | Funciona y sincroniza al volver la red |
| Latencia | Depende de la distancia al centro de datos | Baja, si la lógica no necesita la base central | Instantánea con los datos locales |
| Colaboración en tiempo real | Sí, a través del servidor | Sí, a través del servidor | Limitada: hay que resolver conflictos |
Ponlo en práctica
Saber qué es cada cosa es la mitad del trabajo. La otra mitad es reconocer cuándo usarla.
Interactivo
¿Qué usarías?
Lee cada situación y elige la opción que mejor la resuelve. Fallar aquí no cuenta: es para practicar.
Una agencia monta la web de un despacho de abogados: diez páginas y un blog que se actualiza una vez por semana. Quieren que cargue muy rápido y que alojarla cueste casi nada.
Para recordar
- Jamstack genera las páginas en el build y las sirve desde una CDN; lo dinámico llega por APIs.
- Headless separa el contenido o el comercio de su presentación; MACH lleva esa idea a plataformas de proveedores intercambiables.
- El edge computing ejecuta tu código cerca del usuario, pero la ventaja se pierde si los datos siguen lejos.
- Offline-first guarda una copia local y sincroniza con el servidor; local-first hace del dispositivo la fuente de verdad y usa CRDT para colaborar.
Comprueba lo aprendido
Cuestionario
Responde las 5 preguntas para completar la lección.
1.¿Qué significa que un CMS sea headless?
2.En una web Jamstack, la redacción corrige una errata en el CMS. ¿Cómo llega el cambio a la web?
3.Tu función en el edge consulta en cada petición una base de datos que está en un único centro de datos de otro continente. ¿Qué pasa?
4.¿Qué pieza del navegador permite que una web responda a sus peticiones sin red?
5.¿Qué garantizan los CRDT?