---
title: "Arquitectura orientada a eventos para PWA"
description: "Por qué los eventos enviados por el servidor y EDA pueden encajar mejor en PWA móviles offline-first que las API de petición-respuesta."
date: 2021-12-30
---

Al estudiar los [Server-Sent
Events](https://en.wikipedia.org/wiki/Server-sent_events), tarde o
temprano aparece la [arquitectura orientada a
eventos](https://en.wikipedia.org/wiki/Event-driven_architecture) (EDA).
En realidad, EDA es natural en las aplicaciones web: la usamos casi sin
notarlo cuando añadimos comportamiento JavaScript al HTML.

``` html
<button onclick="myFunction()">Click me</button>
```

La interacción entre el navegador y la persona usuaria se basa en
eventos, por lo que este modelo resulta intuitivo para cualquier
desarrollador web.

También es familiar el modelo navegador-servidor: el navegador envía una
solicitud y recibe el resultado de la acción.

<zoom-img src="/medium/img/d77d10cc3276/image-01.png" alt="Interacción HTTP básica de petición y respuesta" width="100%"></zoom-img>

Esta es la esencia de HTTP: enviar una solicitud y recibir un resultado.

En 2004, [Ian Hickson](https://en.wikipedia.org/wiki/Ian_Hickson)
propuso [extender la respuesta del servidor en el
tiempo](http://ln.hixie.ch/?count=1&start=1083167110), creando un flujo
y procesando el resultado por partes a medida que llega la información.
De esa idea nació Server-Sent Events.

<zoom-img src="/medium/img/d77d10cc3276/image-02.png" alt="Flujo de eventos enviados por el servidor" width="100%"></zoom-img>

El servidor puede ahora transmitir información al cliente como flujo.
Desde EDA, el servidor es el productor, el navegador es el suscriptor y
la conexión HTTP más el código en ambos extremos forman el mecanismo o
cola de eventos.

Este diseño exige tratamiento asíncrono y tolerancia a la pérdida de
eventos individuales. Por ello resulta natural un flujo de vuelta:
solicitudes del navegador que confirman la recepción de los eventos del
servidor.

<zoom-img src="/medium/img/d77d10cc3276/image-03.png" alt="Confirmación de eventos mediante HTTP" width="100%"></zoom-img>

Las confirmaciones se pueden enviar con POST a un servicio común,
indicando el ID del evento. Pero eso no resuelve por sí solo las
pérdidas: la confirmación también puede perderse. La aplicación debe
tolerar un mensaje ausente. Si no llega una reacción esperada a tiempo,
reenvía el evento; cada suscriptor decide si ya lo trató o no lo
recibió.

La propuesta interesante es usar ese canal de confirmación como un SSE
invertido y enviar mensajes del navegador al servidor también de forma
asíncrona. En vez de muchos servicios síncronos para acciones distintas,
la aplicación tiene dos canales: uno directo para mensajes del navegador
y otro de vuelta para eventos del servidor.

<zoom-img src="/medium/img/d77d10cc3276/image-04.png" alt="Dos canales de eventos entre navegador y servidor" width="100%"></zoom-img>

Este modelo encaja bien con PWA móviles que deben funcionar sin
conexión. Mantienen datos de trabajo en `localStorage` o `indexedDb` y
los intercambian con el servidor cuando es posible. La API web puede
reducirse a dos servicios: abrir el canal de eventos del servidor e
informar un evento del navegador.

En aplicaciones de este tipo, REST, GraphQL y gRPC dejan de ser el
centro del diseño. No afirmo que EDA los sustituya: para PWA móviles que
pasan constantemente entre offline y online, los flujos de eventos
pueden encajar mejor; para aplicaciones web con conexión estable, las
tecnologías clásicas de petición-respuesta siguen siendo más
previsibles.
