Slovník pojmů
Mercure
Protokol pro jednosměrné doručování živých aktualizací ze serveru klientům, s hubem, topics, autorizací a obnovou spojení.
Stručná definice
Publish/subscribe pro webové klienty nad HTTP a SSE.
Mercure odděluje backend, který změnu publikuje, od prohlížečů nebo dalších klientů, kteří ji odebírají. Hub drží dlouhodobá HTTP spojení, porovnává odběry s topics a rozesílá odpovídající aktualizace. Hodí se například k doplnění běžného API o živou změnu stavu objednávky.
Přenos z hubu k subscriberovi používá Server-Sent Events. Je tedy primárně jednosměrný server → klient a není totožný s WebSocketem. Klient po stejném SSE spojení neposílá příkazy zpět; změny obvykle zapisuje samostatným HTTP požadavkem do API.
Jaký problém řeší
Rychlé doručení změny bez pravidelného pollingu
Když klient každých několik sekund zjišťuje, zda se něco změnilo, vzniká zbytečná prodleva i provoz. Mercure umožní backendu oznámit změnu připojeným klientům ihned po jejím vzniku.
- živá změna stavu objednávky, platby nebo expedice v administraci e-shopu
- průběh importu, exportu a jiné dlouhotrvající serverové úlohy
- aktualizace dashboardu, upozornění a spolupráce více uživatelů nad jedním zdrojem
- doručení veřejných i soukromých aktualizací více subscriberům bez přímé vazby na publishera
- doplnění autoritativního HTTP API o signál, že má frontend změnit nebo znovu načíst data
Praktický příklad
Živý stav objednávky v administraci e-shopu
PHP backend nejprve bezpečně změní objednávku v databázi. Potom publikuje do hubu update pro topic konkrétní objednávky. Otevřené administrace, které tento topic odebírají a mají k němu oprávnění, obdrží JSON payload a aktualizují řádek nebo znovu načtou detail přes API.
Ukázka používá parametr topic ze stabilní řady Mercure 0.x. Specifikace Mercure 1.0, která je aktuálně označená jako alpha, místo něj zavádí přesný matcher match a pro URL vzory match_urlpattern. Syntaxe klienta i tokenu proto musí odpovídat verzi nasazeného hubu. Samotná znalost topicu neopravňuje klienta k odběru soukromých aktualizací.
JavaScript
const hub = new URL('https://hub.example.cz/.well-known/mercure');
hub.searchParams.append('topic', 'https://shop.example.cz/orders/42');
const events = new EventSource(hub, { withCredentials: true });
events.onmessage = ({ data }) => {
const update = JSON.parse(data);
renderOrderStatus(update.status);
};
events.onerror = () => showTemporaryConnectionWarning();
Jak funguje
Textový diagram: backend → Mercure hub → SSE spojení → prohlížeč → ověření přes API
Diagram popisuje běžný tok, nikoli jedinou možnou implementaci. Hub lze provozovat samostatně nebo může aplikace protokol implementovat přímo.
- 1. Backend změní stav Aplikace uloží například nový stav objednávky. Databázový zápis je autoritativní; real-time zpráva jej nenahrazuje.
- 2. Publisher odešle update Backend pošle autorizovaný HTTPS POST do hubu. Update obsahuje alespoň topic a obvykle data; pro soukromá data je označen jako private.
- 3. Hub vybere subscribery Hub porovná topic s matchery aktivních odběrů a u private update zkontroluje, zda má subscriber oprávnění daný topic přijmout.
- 4. SSE doručí událost Hub zapíše update jako text/event-stream do dlouhodobého HTTP spojení. Prohlížeč událost zpracuje bez nového pollingu.
- 5. Frontend aktualizuje obrazovku Klient použije payload nebo znovu načte zdroj přes API. Po výpadku srovná zobrazení s aktuálním autoritativním stavem.
Hlavní části a principy
Hub směruje aktualizace, topic je identifikuje a token omezuje přístup
Jednotlivé role mají odlišnou odpovědnost. Jejich záměna často vede k chybné autorizaci nebo přehnaným očekáváním od doručení.
Hub
Server přijímající publikace a obsluhující odběry. Udržuje mnoho dlouhodobých spojení, distribuuje matching updates a prosazuje provozní a autorizační pravidla.
Publisher a subscriber
Publisher vlastní zdroj a oznamuje jeho novou verzi. Subscriber je klient, který odebírá vybrané topics; typicky prohlížeč, mobilní aplikace nebo jiný server.
Topic, matcher a update
Topic je textový identifikátor aktualizovaného zdroje, často IRI. Subscriber vybírá topics pomocí selektoru či matcheru podle verze protokolu. Update nese alespoň jeden topic, novou reprezentaci či dílčí změnu a může být veřejný nebo private.
SSE spojení
Odběr běží jako dlouhodobá HTTP odpověď typu text/event-stream. Na rozdíl od WebSocketu nejde o plně obousměrný kanál; pro zápis klient používá samostatné HTTP/API volání.
JWT a oprávnění
JWT nese podepsaná oprávnění, nikoli šifrovaná data. Stabilní implementace 0.x používají claims mercure.publish a mercure.subscribe. Specifikace 1.0 alpha přechází na OAuth 2.0 JWT access token s authorization_details a matchery topiců; formát musí odpovídat verzi hubu.
Reconnect a Last-Event-ID
EventSource se po přerušení typicky znovu připojí. Identifikátor poslední události může hubu umožnit obnovit chybějící aktualizace, jen pokud je uchovává a dané ID zná; není to automatická nekonečná historie.
Výhody, omezení a časté chyby
Jednodušší doručení do prohlížeče výměnou za péči o spojení, práva a obnovu
Přínosy
- server může klienta informovat ihned bez krátkého pollingu
- nativní EventSource pracuje nad běžným HTTP a automaticky se pokouší obnovit spojení
- jeden hub oddělí publishera od většího počtu subscriberů
- topics umožňují směrovat aktualizace konkrétním zdrojům nebo skupinám zdrojů
- private updates mohou být doručeny pouze oprávněným subscriberům
Omezení a časté chyby
- považovat SSE za obousměrný protokol a snažit se stejným spojením posílat příkazy serveru
- publikovat citlivý payload jako veřejný update nebo povolit příliš široké topic selectors
- spoléhat na update jako na jediný autoritativní stav místo databáze a API
- předpokládat, že každý odpojený klient vždy získá celou historii bez nastavené retence a obnovy
- ignorovat limity spojení, CORS, expiraci tokenu, bufferování proxy a ukončování neaktivních spojení
Porovnání a vhodnost
Mercure je cesta k webovým subscriberům, ne univerzální backendový broker.
Oproti nízkoúrovňovým Server-Sent Events přidává Mercure standardizovanou publikaci, hub, topics, autorizaci, discovery a mechanismy obnovy. Oproti webhooku udržuje dlouhé spojení se subscribery; webhook je samostatný HTTP request mezi systémy při konkrétní události.
Oproti RabbitMQ míří Mercure především na doručování aktualizací webovým klientům. RabbitMQ je message broker pro backendovou komunikaci s frontami, acknowledgements a řízením consumerů. Mercure hub proto není automatická náhrada integrační fronty.
WebSocket poskytuje plně obousměrnou komunikaci a hodí se tam, kde obě strany často posílají zprávy. Mercure nad SSE je přirozenější, když server hlavně informuje klienty a jejich příkazy dál procházejí běžným HTTP API.
Na co myslet v produkci
Real-time vrstva musí přežít výpadek bez úniku dat a rozbití stavu.
Kvalita řešení se projeví při odpojení, expiraci tokenu a změně oprávnění, nikoli jen při šťastném průchodu na lokálním počítači.
- navrhnout topics tak, aby se daly bezpečně autorizovat a nezveřejňovaly zbytečné citlivé údaje; autorizace se musí vyhodnocovat na hubu, ne jen ve frontendu
- správně nastavit CORS, cookies nebo Authorization header podle zvoleného klienta a nepoužívat dlouhodobé či příliš široké tokeny
- v reverse proxy vypnout nežádoucí bufferování event streamu a nastavit timeouty, keep-alive i HTTP/2 nebo novější podle možností infrastruktury
- měřit počet spojení, latenci publikace, odmítnuté odběry, reconnecty, ztracené cursory a přetížené klienty
- po reconnectu nebo podezřelé mezeře načíst aktuální zdroj z API; real-time update je optimalizace doručení změny, nikoli zdroj pravdy
Časté otázky
Mercure bez častých záměn
Používá Mercure WebSocket?
Ne pro standardní doručení aktualizací subscriberům. Mercure používá Server-Sent Events přes dlouhodobou HTTP odpověď typu text/event-stream.
Může klient poslat změnu serveru přes stejné SSE spojení?
Ne. SSE je jednosměrné ze serveru ke klientovi. Klient změnu obvykle odešle samostatným POST, PUT nebo PATCH požadavkem do API.
Zaručí Last-Event-ID, že klient nikdy neztratí update?
Ne samo o sobě. Pomáhá určit poslední přijatou událost, ale hub musí mít odpovídající historii a klient musí umět obnovit stav, když je cursor neznámý nebo příliš starý.
Je JWT nutné i pro veřejné aktualizace?
Subscriber může podle politiky hubu přijímat veřejné updates bez tokenu. Publisher musí být autorizovaný a private updates smějí dostat jen subscribeři s oprávněním k odpovídajícím topics.
Nahrazuje Mercure RabbitMQ nebo databázi?
Ne. Hub doručuje aktualizace klientům, ale databáze zůstává zdrojem pravdy a backendová fronta může dál řešit spolehlivé asynchronní zpracování mezi službami.
Jak navrhuji API a integrační toky v praxi
Živé aktualizace vážu na autoritativní data, oprávnění a bezpečnou obnovu.
U objednávek a provozních aplikací odděluji zápis business stavu od jeho doručení do prohlížeče a počítám s výpadkem každé vrstvy.