Echtzeit-Kommunikation mit GraphQL I/O

Seite 2: Etablierte Schnittstellen sind unpassend

Inhaltsverzeichnis

Wie muss eine Anwendungsschnittstelle ausgestaltet sein, damit sich darüber eine Omnichannel-Echtzeit-Strategie sinnvoll fahren lässt? Echtzeit erfordert von der Anwendungsschnittstelle Push- statt Pull-Kommunikation. Denn die entbindet den Client von der Aufgabe, den Server ständig nach neuen Daten fragen zu müssen. Stattdessen lässt sich der Client die Daten so oft wie möglich aktiv vom Server anliefern. Alternativen in Form konstanten Pollings durch die Clients würden unnötige Last auf der Infrastruktur erzeugen. Mit Blick auf mobile Geräte fielen für den Anwender durch das Polling auch potenziell Kosten durch getaktete Verbindungen an und der Akku wird strapaziert.

Ohnehin sind heute die mobilen Geräte und Funkverbindungen der wichtigste Zugangspunkt zu betrieblichen Informationssystemen. Bandbreite, Latenzen und Kosten sind deshalb entscheidende Faktoren der Datenzugriffsmuster. Client und Server sollten deshalb stets einen angemessenen Datenaustausch pflegen. Sprich: Der Client sollte den benötigten Umfang und Detailgrad der Daten festlegen können. Denn je kleiner etwa der Bildschirm, desto weniger Inhalte und Daten lassen sich überhaupt darstellen. Desto kleiner sollten dann auch die einzelnen Datenlieferungen ausfallen.

Bei Funkverbindungen kommt auch zum Tragen, dass sich innerhalb einer WLAN- oder LTE-Funkzelle oft viele Geräte tummeln. Je mehr Geräte angemeldet sind und Daten austauschen, desto geringer fällt die verfügbare Bandbreite je Gerät aus. Je mehr Daten dann übertragen werden müssen, desto länger dauert es, bis die Übertragung abgeschlossen ist. Die Verzögerungen sind für die Anwender spürbar.

Der Omnichannel-Strategie ist auch geschuldet, dass die Schnittstelle bequem anpassbar und erweiterbar sein muss. Nur so lässt sich für zukünftige Kanäle und Clients der angemessene Datenaustausch garantieren. Sollte sich überdies das Datenmodell einmal ändern, dann müssen diese Änderungen wiederum schnell über die Schnittstelle reflektiert werden können.

Schlussendlich muss sich die Echtzeit-Kommunikation auch möglichst einfach und konsistent durch die Architekten und Entwickler umsetzen lassen, sowohl auf Client- als auch Serverseite. Wäre der Entwicklungsaufwand zu groß oder müssten zu viele Workarounds geschaffen werden, dann wird die Schnittstelle unzuverlässig und womöglich unwartbar.

Auf die Anforderungen variabler Datenzugriffsmuster (Englisch: data access pattern), adäquater Datenkommunikation, Echtzeit-Aktualisierung, Erweiterbarkeit und einfache Implementierung hin abgeklopft, stellt sich heraus: Keine der etablierten Schnittstellen RPC, SOAP oder REST kann sie vollständig erfüllen.

Remote Procedure Call (kurz RPC) war die erste API für verteilte Systeme. Sie entstand Ende der 1970er Jahre und ist somit der Urahn der etablierten Schnittstellentechnologien. Damals war an datenbereitstellende Services noch gar nicht zu denken. Stattdessen war die Motivation hinter RPC, auf einem fernen System eine Funktion oder Prozedur so aufzurufen, als wäre sie ein Bestandteil des eigenen Systems. RPC ist deshalb rein funktionsorientiert. Einfacher sowie eingängiger lässt sich das funktionsorientierte Programmierprinzip nicht auf verteilte Systeme übertragen.

Die Anzahl der Parameter und ihre Reihenfolge sind bei RPC exakt definiert. Gleichzeitig sind Parameter und Rückgabewerte typisiert und die ausgetauschten Daten dementsprechend eindeutig. Vorausgesetzt die API ist feingranular und umfangreich aufgebaut, ist der Client in der Lage, ganz spezifische Daten abzurufen und sie je nach Bedarf zusammenzustellen. Variierende Data Access Pattern stellen für RPC in dieser Hinsicht weniger ein Problem dar. Aber: Die Granularität muss auf Serverseite explizit so vorgesehen und implementiert sein.

Entwickler und Architekten müssen sich für die Aggregation der Daten aber ein genaues Verständnis der Domäne und der Schnittstelle erarbeiten, um spezielle Aufrufreihenfolgen einhalten oder die richtigen Informationen übergeben zu können. Ein Beispiel dafür sind initiierende RPCs, die einen Handler oder ein Kontextobjekt erzeugen, die im weiteren Verlauf als Parameter verwendet werden müssen. Je mehr Funktionsaufrufe zu koppeln sind, desto höher wird der Kommunikationsaufwand ausfallen. Damit fällt die Datenkommunikation unter Umständen nicht immer adäquat aus.

Insgesamt entsteht zwischen Client und Server aufgrund der Funktionsorientierung überdies eine sehr enge Kopplung. Die Konsequenz: Muss man die Schnittstelle einmal anpassen oder erweitern, lässt sich das oft nur durch zusätzliche Funktionen mit angepassten Parameterfolgen umsetzen. Damit die Schnittstelle nicht wild wuchert, müssen diese Ergänzungen maß- und planvoll sein. Denn nachträgliche Änderungen an bereits existierenden Funktionen führen dazu, dass alle Clients überarbeitet und neu ausgerollt werden müssen. Je mehr Clientimplementierungen es gibt, desto umfangreicher fallen die Nacharbeiten aus. Die Erweiterbarkeit der Schnittstelle ist also gegeben, aber an bestimmte Voraussetzungen wie die Orthogonalität geknüpft. Bei RPC gilt das Pull- statt Push-Prinzip.