Volver al inicio

Notificaciones SSE en SPA: en tiempo real sin sondeo

El artículo describe la arquitectura de notificaciones asíncronas en SPA basada en SSE y Mercure. Integración con CDC para rastrear cambios en BD, reutilización de esquemas OpenAPI para tipado. Ejemplos de código y diagramas para desarrolladores.

Notificaciones push SSE en SPA: arquitectura y código
Advertisement 728x90

Actualizaciones Asíncronas de Datos en SPAs Usando SSE y Mercure

Las aplicaciones frontend requieren actualizaciones constantes de datos para reflejar cambios en el backend. Las llamadas API estándar capturan el estado en el momento de la respuesta, pero el backend continúa procesando eventos: recargas de cuenta, moderación de contenido, respuestas de soporte. Para abordar esto, se utilizan mecanismos de push basados en SSE, integrados con la especificación OpenAPI existente.

El sistema combina un enfoque pull (solicitudes periódicas) con push (notificaciones en tiempo real). SSE proporciona un flujo de eventos unidireccional sobre HTTP/2, minimizando la carga en comparación con el polling.

Casos de Uso para Notificaciones Asíncronas

Las notificaciones asíncronas son críticas en procesos empresariales:

Google AdInline article slot
  • Recarga de saldo: Mostrar el estado actual para compras inmediatas.
  • Moderación de contenido: Actualizar el estado después de la revisión.
  • Respuestas de soporte: Notificación instantánea sobre un nuevo ticket.

En un caso típico, el usuario—un anunciante o contratista—rastrea contadores de solicitudes: el número que requiere acción, comentarios no leídos, verificaciones de colocación. Estos datos están disponibles a través del endpoint de API /rest/User/info (operationId: getInfo).

/rest/User/info:
  get:
    tags:
      - Usuario
    summary: Devuelve información sobre el usuario actual
    operationId: getInfo
    responses:
      200:
        description: Información sobre el usuario actual
        content:
          application/json:
            schema:
              type: object
              properties:
                id:
                  type: integer
                  format: int32
                  minimum: 0
                locale:
                  type: string
                  enum: [ru, en]
                login:
                  type: string
                  minimum: 3
                  maximum: 320
                seoCounters:
                  $ref: '#/components/schemas/SeoCounters'

El esquema SeoCounters define la estructura:

SeoCounters:
  type: object
  properties:
    nofRequests:
      type: integer
      format: int32
      minimum: 0
    nofLinksStatusNeedApprove:
      type: integer
      format: int32
      minimum: 0
    nofLinksWithUnreadComments:
      type: integer
      format: int32
      minimum: 0
    nofChanges:
      type: integer
      format: int32
      minimum: 0
    nofPlacementCheck:
      type: integer
      format: int32
      minimum: 0

Integración de CDC y Plataforma de Datos

Los cambios en la tabla user_counters se rastrean mediante CDC (Captura de Cambios de Datos). El flujo de modificaciones se envía a la Plataforma de Datos—un sistema ETL corporativo. Desde allí, los eventos se envían a la interfaz de usuario a través de un hub SSE.

Google AdInline article slot

La arquitectura utiliza un modelo hexagonal: la especificación OpenAPI genera automáticamente adaptadores REST y tipos TypeScript. Para el frontend, los tipos se ven así:

/* Generado por orval */
export interface SeoCounters {
  nofRequests?: number;
  nofLinksStatusNeedApprove?: number;
  nofLinksWithUnreadComments?: number;
  nofChanges?: number;
  nofPlacementCheck?: number;
}

export type GetInfo200 = {
  id: number;
  locale: 'ru' | 'en';
  login: string;
  seoCounters?: SeoCounters;
};

Estos tipos se reutilizan para procesar eventos SSE, garantizando seguridad de tipos.

Implementación de SSE en la Aplicación

SSE (Eventos Enviados por el Servidor) es un estándar para push del servidor, compatible con navegadores. EventSource se conecta al endpoint:

Google AdInline article slot
const evtSource = new EventSource('/sse-endpoint', {
  withCredentials: true,
});

evtSource.onmessage = (event) => {
  const data = JSON.parse(event.data);
  // Actualizar el almacén con datos tipados
  updateSeoCounters(data.seoCounters);
};

Para autorización, temas y escalabilidad, se utiliza Mercure—un hub de código abierto basado en SSE. El hub acepta publicaciones vía REST con JWT y transmite a suscriptores.

Ejemplo de publicación:

curl -d 'topic=https://example.com/books/1' \
     -d 'data={"foo": "valor actualizado"}' \
     -H 'Authorization: Bearer <JWT>' \
     -X POST https://hub/.well-known/mercure

JWT define derechos de publicación/suscripción para temas. Mercure se despliega como un contenedor con una base de datos externa, integrando con flujos CDC.

Ventajas del Enfoque

  • Reutilización de Esquemas: Las estructuras OpenAPI se usan en pull y push sin duplicación.
  • Tiempo Real: Los cambios se reflejan instantáneamente sin polling.
  • Escalabilidad: El hub Mercure distribuye la carga.

Lista de contadores clave para monitoreo:

  • nofRequests — solicitudes de acción.
  • nofLinksStatusNeedApprove — enlaces pendientes de aprobación.
  • nofLinksWithUnreadComments — comentarios no leídos.
  • nofPlacementCheck — verificaciones de colocación.

Conclusiones Clave

  • SSE con Mercure proporciona notificaciones push tipadas sin la sobrecarga de WebSocket.
  • CDC captura cambios en la base de datos en tiempo real para procesos ETL.
  • La generación automática de tipos TypeScript desde OpenAPI asegura consistencia de datos.
  • El enfoque escala para sistemas de alta carga con miles de usuarios.
  • JWT en Mercure gestiona el acceso a temas de notificación.

— Editorial Team

Advertisement 728x90

Leer después