HTTP-Feeds: Asynchrone Schnittstellen ohne Kafka oder RabbitMQ

Seite 2: HTTP-Feeds als Alternative

Inhaltsverzeichnis

Solche durch Middleware verursachten Abhängigkeiten sollten Entwicklerinnen und Entwickler möglichst meiden oder zumindest minimieren. Denn asynchrone Schnittstellen lassen sich auch ganz ohne Middleware mit klassischen HTTP-Endpunkten als Feeds umsetzen. Feeds stellen dabei eine chronologische Folge von Daten zur Verfügung.

Konzeptionelle Darstellung eines Data-Feeds (Abb. 2).

Die für die Daten verantwortlichen Systeme stellen technisch einen HTTP-Endpoint zur Verfügung, über den sich die Daten abfragen lassen. Consumer greifen per GET-Abfrage darauf zu und können sowohl einmalig historische als auch kontinuierlich neue Daten verarbeiten.

HTTP-Feeds lassen sich in unterschiedlichsten Anwendungsszenarien zum Entkoppeln von Systemen einsetzen. Bei der Datenreplikation gilt es, alle Entitäten eines Geschäftsobjekts in einem definierten Format bereitzustellen und von den den Feed empfangenden Systemen (Consumer) in einer lokalen Datenbank in der benötigten Form abzuspeichern. Im Feed sind immer alle Geschäftsobjekte mindestens einmal vorhanden, wobei im Falle einer Änderung der komplette aktuelle Zustand als Feed-Eintrag erneut am Ende hinzukommt. Ältere Einträge, die den gleichen fachlichen Schlüssel haben (zum Beispiel Kundennummer oder Bestellnummer), können dann entfallen. Subscriber des Feeds erhalten so immer den aktuellen Stand aller Geschäftsobjekte und können diesen auch nachträglich erneut einspielen, beispielsweise dann, wenn in der lokalen Datenbank ein weiteres Attribut abgespeichert werden soll. Datenreplikation dient dazu, schnelle Lookups unabhängig von der Verfügbarkeit des Quellsystems durchführen zu können, beispielsweise um Kundendaten anhand einer Kundennummer zu lesen oder um Datenanalysen in einem separaten Analysesystem durchzuführen.

Eine weitere Form der Feeds sind Event-Feeds. Hierbei werden fachliche Ereignisse, genannt Domain Events, in einem Feed publiziert. Sie beschreiben, was zu einem bestimmten Zeitpunkt in einem System passiert ist, enthalten aber nicht alle Informationen des betroffenen Geschäftsobjekts. Zum Beispiel kann eine Betrugsprüfung zu einem negativen Ergebnis führen (Betrugsverdacht) oder eine Kundin kann ihre E-Mail-Adresse geändert haben. Den Feed empfangende Systeme (Consumer) können anhand dieser Events Aktionen auslösen, die in ihrem fachlichen Kontext relevant sind.

Interessanterweise könnten auch Daten-Feeds entsprechende Aktionen auslösen: Wenn eine neue oder aktualisierte Entität im Feed vorhanden ist, lässt sich im Consumer-System eine entsprechende fachliche Aktion auslösen. Beispielsweise lässt sich ein neuer Eintrag in einem Kunden-Feed dazu nutzen, die E-Mail-Adresse einer Kundin oder eines Kunden in das E-Mail-Marketing-System einzutragen.

In beiden Fällen ist es wichtig, stets auf fachliche und technische Idempotenz in den Consumer-Systemen zu achten, da es häufiger vorkommen kann, dass ein Feed aus technischen Gründen neu einzulesen ist. Darüber hinaus muss geregelt sein, wie damit zu verfahren ist, wenn ein Geschäftsobjekt gelöscht werden soll.

HTTP-Feeds lassen sich über verschiedene Techniken, Datenformate und Protokolle umsetzen.

Atom

Zu den prominenten Feed-Techniken zählt das Atom-Syndication-Format. Vergleichbar zum RSS-Standard stellen Nachrichtenwebseiten und Blogs per Atom typischerweise neue Artikel in Form einer XML-Schnittstelle bereit. Dieses Format enthält ein spezifiziertes Datenmodell, das für Nachrichten und Blogbeiträge optimiert ist, sich aber grundsätzlich für beliebige Datensätze nutzen lässt.

Das Atom-Format verwendet XML (Abb. 3).

Atom beschreibt allerdings nur ein Format, nicht aber das Protokoll, das den Informationsabruf regelt. Daher ist auch das kontinuierliche Lesen neuer Einträge bei Atom nicht spezifiziert.

Polling von REST-APIs

Ein Feed lässt sich auch vollständig auf reinen REST-APIs aufbauen, wobei neue Einträge in einem HTTP-GET-Endpoint chronologisch aufsteigend als Collection bereitstehen. Um bei großen Datenmengen übermäßig lange Antwortzeiten zu vermeiden, empfiehlt es sich, die Anzahl der Einträge pro Request zu limitieren – beispielsweise auf 1000 Einträge. Durch eine Verlinkung lassen sich dann weitere Daten abrufen, bis alle verarbeitet sind.

In der REST-API sind die chronologisch sortierten Einträge durch einen next-Link verkettet (Abb. 4).

Über ein Polling-Verfahren wird eine Subscription umgesetzt: Sobald alle historischen Einträge verarbeitet sind, erhält der Consumer ein leeres Array als Response. Der Consumer führt nun in einer Endlosschleife einfach weitere Anfragen auf die letzte verlinkte URL durch. Auf leere Responses folgt beim klassischen Polling eine definierte Pause, bevor mit einem weiteren GET-Aufruf die Prüfung auf neue Einträge erfolgt.

Durch ein Long-Polling-Verfahren lässt sich die Latenz bei der Verarbeitung neuer Events minimieren (Abb. 5).

Alternativ bietet ein Long-Polling-Verfahren dem Server die Möglichkeit, den Request so lange offen zu halten, bis entweder neue Daten vorhanden sind oder ein definiertes Time-out abgelaufen ist. Der Client kann dann sofort eine neue Anfrage stellen. Das Long-Polling-Verfahren minimiert die Latenz beim Verarbeiten neuer Einträge, auf Kosten offener Connections zum Server. Die Open-Source Library rest-feeds implementiert ein solches Long-Polling-Verfahren mittels REST-APIs sowohl für Daten-Feeds als auch für Event-Feeds.

Server-Sent Events nach HTML5-Standard

Eine dritte Option zum Umsetzen von HTTP-Feeds bieten Server-Sent Events. Wie der Name dieses HTML-Standards andeutet, erfolgt die Kommunikation der Daten hierbei One-Way vom Server zum Client. Das Client-System baut eine dauerhafte Verbindung zu einem HTTP-Endpoint auf, über die der Server Daten im MIME-Type-Format text/event-stream schreibt – ohne die Verbindung zu beenden. Der Client kann die Datensätze, die durch eine Leerzeile voneinander getrennt sind, kontinuierlich lesen und verarbeiten. Kommt es zu einem Verbindungsabbruch, lässt sich die Verarbeitung durch die Angabe der Last-Event-ID als Header-Feld an einem bestimmten Datensatz fortsetzen.

Gestreamte Server-Sent Events sind durch Leerzeilen getrennt (Abb. 6).

Server-Sent Events eignen sich für die asynchrone Bereitstellung von Daten und lassen sich in allen relevanten Browsern per JavaScript nutzen. Das auf Langlebigkeit ausgelegte Connection-Handling erschwert allerdings den Betrieb und das Debugging, insbesondere bei Endpoints, die mehrere Millionen Einträge enthalten. Darüber hinaus ist die Response kein reines JSON, was zu Kompatibilitätseinschränkungen beim Tooling führen kann.