Förderjahr 2018 / Project Call #13 / ProjektID: 3361 / Projekt: Hedgehog Cloud
Webanwendungen zu erstellen, das ist ja seit langem keine Hexerei mehr. Es gibt zahllose Vorlagen, an denen man sich orientieren kann. Wenn man aber auch Updates vom Server an den Client benötigt, ist es mit einer Vorlage nicht getan.
Markus und ich, das Kernteam von Hedgehog Cloud, sind mit klaren Architekturvorstellungen in dieses Projekt gestartet: eine "PWA" soll es sein, mit Offline-Support soweit möglich. Im Frontend könnte es React oder Vue werden; da erwarten wir die beste Produktivität. JSON Web Tokens (JWT) kommen zur Authentifizierung zum Einsatz. Isomorphic, also der gleiche Code auf Client und Server, deuten in Richtung JavaScript full-stack. Und: kommuniziert wird mit GraphQL, das ist ergonomischer und moderner als REST, hat eine Spezifikation die uns in der Wahl der Software Flexibilität bewahrt, und - ganz wichtig - unterstützt neben der üblichen Request/Response Kommunikation auch sogenannte Subscriptions für Updates vom Server, beispielsweise über Websockets.
Der erste Schritt war es deshalb, eine passende Projektvorlage zu finden. Mit den vielen Tools wie Babel, Webpack, eslint, flow, etc., die alle in eine kohärente Projektstruktur zusammengefügt werden wollen, ist gleich am Anfang Entscheidungsarbeit gefragt. Idealerweise integriert die Vorlage auch schon unsere Bibliotheken der Wahl - das wären dann React (Frontend) und Apollo (GraphQL) - und unterstützt so nette dinge wie Server-Side-Rendering, ServiceWorkers - dazu vielleicht in einem späteren Post mehr - und eben WebSockets/GraphQL Subscriptions.
Mit dem React Starter Kit, konfiguriert für Apollo, sind wir da auch fündig geworden, bis auf die Subscriptions über WebSockets. Dafür waren dann noch eigene Konfigurationen notwendig: die beiden Kommunikationsschnittstellen apollo-link-http und apollo-link-ws in Einklang bringen, den Server zum Verarbeiten von Subscriptions zu bringen, und sicherstellen, dass die Authentifizierung auch über WebSockets wie geplant funktioniert.
Das Setup muss natürlich auch getestet werden, und damit belasten wir gleich so gut wie alle Ebenen unserer Infrastruktur:
- fürs Server-Side-Rendering wird das React-Frontend schon auf dem Server ausgeführt. Über GraphQL werden die notwendigen Daten per Query abgefragt, und der Client bekommt eine fix-fertige Seite geliefert.
- im Browser öffnet Apollo sofort ein WebSocket; der Authentifizierungs-Cookie wird automatisch mitübertragen, der aktuelle User ist in der Subscription verfügbar. Queries werden nicht ausgeführt; alle Daten wurden ja schon serverseitig geladen.
- mit dem "Refresh"-Button wird ein Query abgesetzt, kurz später aktualisieren sich die ersten beiden Zeilen: da Apollo die Ergebnisse der Queries cached, wirkt sich jedes Update nicht nur auf den ab, der die Daten abgerufen hat, sondern auf jeden, der sie benötigt.
- mit dem "Execute"-Button wird eine Mutation ausgeführt. Das Ergebnis wird nicht gecached, weil eine Mutation keinen dahinterliegenden Datensatz hat. Allerdings stoßen wir damit am Server ein Update der Subscription an, und da unser Query konfiguriert ist, Daten aus dieser Subscription verwenden zu können, passiert auch hier ein Update.
Mit diesen Arbeiten haben wir eine solide Kommunikationsgrundlage für alle unsere Belange: ob Projekte vom Server laden, oder zum Peer-Coding mehrere Anzeigen synchronisieren, alles kein Problem!