Asynchroniczne aktualizacje danych w SPA za pomocą SSE i Mercure
Aplikacje frontendowe wymagają ciągłego odświeżania danych, aby odzwierciedlać zmiany zachodzące po stronie backendu. Standardowe zapytania API przechwytują stan w momencie odpowiedzi, ale backend nadal przetwarza zdarzenia: doładowania kont, moderację treści, odpowiedzi działu wsparcia. Aby rozwiązać ten problem, stosuje się mechanizmy push oparte na SSE, zintegrowane z istniejącą specyfikacją OpenAPI.
System łączy podejście pull (okresowe zapytania) z push (powiadomieniami w czasie rzeczywistym). SSE zapewnia jednokierunkowy strumień zdarzeń przez HTTP/2, minimalizując obciążenie w porównaniu z pollingiem.
Scenariusze zastosowania asynchronicznych powiadomień
Asynchroniczne powiadomienia są kluczowe w procesach biznesowych:
- Doładowanie salda: wyświetlanie aktualnego stanu dla natychmiastowego zakupu.
- Moderacja treści: aktualizacja statusu po weryfikacji.
- Odpowiedzi wsparcia: natychmiastowe powiadomienie o nowym zgłoszeniu.
W typowym przypadku użytkownik — reklamodawca lub wykonawca — śledzi liczniki zgłoszeń: liczbę wymagających działania, nieprzeczytanych komentarzy, weryfikacji publikacji. Te dane są dostępne przez endpoint API /rest/User/info (operationId: getInfo).
/rest/User/info:
get:
tags:
- User
summary: Zwraca informacje o aktualnym użytkowniku
operationId: getInfo
responses:
200:
description: Informacje o aktualnym użytkowniku
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'
Schemat SeoCounters definiuje strukturę:
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
Integracja CDC i Data Platform
Zmiany w tabeli user_counters są śledzone przez CDC (Change Data Capture). Strumień modyfikacji jest przekazywany do Data Platform — korporacyjnego systemu ETL. Stamtąd zdarzenia są wypychane do UI przez hub SSE.
Architektura wykorzystuje model heksagonalny: specyfikacja OpenAPI automatycznie generuje adaptery REST i typy TypeScript. Dla frontendu typy wyglądają tak:
/* Generated by 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;
};
Te typy są ponownie wykorzystywane do obsługi zdarzeń SSE, zapewniając bezpieczeństwo typów.
Implementacja SSE w aplikacji
SSE (Server-Sent Events) — standard dla pushy serwerowych, obsługiwany przez przeglądarki. EventSource łączy się z endpointem:
const evtSource = new EventSource('/sse-endpoint', {
withCredentials: true,
});
evtSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// Aktualizacja stanu z danymi typowanymi
updateSeoCounters(data.seoCounters);
};
Do autoryzacji, tematów i skalowania stosuje się Mercure — open-source hub oparty na SSE. Hub przyjmuje publikacje przez REST z JWT i rozsyła subskrybentom.
Przykład publikacji:
curl -d 'topic=https://example.com/books/1' \
-d 'data={"foo": "updated value"}' \
-H 'Authorization: Bearer <JWT>' \
-X POST https://hub/.well-known/mercure
JWT definiuje uprawnienia do publikacji/subskrypcji według tematów. Mercure jest wdrażany jako kontener z zewnętrzną bazą danych, integruje się ze strumieniami CDC.
Zalety podejścia
- Ponowne wykorzystanie schematów: Struktury OpenAPI są używane w pull i push bez duplikacji.
- Czas rzeczywisty: Zmiany są odzwierciedlane natychmiast bez polling.
- Skalowalność: Hub Mercure rozkłada obciążenie.
Lista kluczowych liczników do monitorowania:
nofRequests— zgłoszenia do działania.nofLinksStatusNeedApprove— linki do zatwierdzenia.nofLinksWithUnreadComments— nieprzeczytane komentarze.nofPlacementCheck— weryfikacje publikacji.
Co jest ważne
- SSE z Mercure zapewnia typowane powiadomienia push bez nakładki WebSocket.
- CDC przechwytuje zmiany w bazie danych w czasie rzeczywistym dla procesów ETL.
- Autogeneracja typów TypeScript z OpenAPI gwarantuje spójność danych.
- Podejście skaluje się dla systemów high-load z tysiącami użytkowników.
- JWT w Mercure zarządza dostępem do tematów powiadomień.
— Editorial Team
Brak komentarzy.