Interview: Full-Stack Architekturen

Wir reden und schreiben zwar viel über Frontend-Architektur, aber die Architektur-Geschichte endet natürlich nicht mit der Service-Kommunikation. Deswegen möchten ich heute in diesem Interview mit unserem Fullstack-Experten Daniel Murrmann auch die Seite des Backends beleuchten.

Manfred: Mit Micro Frontends möchte man ja die Vorteile von Micro Services in den Client holen. Wie siehst Du das Verhältnis zwischen den beiden Architektur-Spielarten?

Daniel: Aus meiner Sicht vollkommen unabhängig. Es kann ja zu jeder Micro Service Infrastruktur auch mehrere separate Apps/Micro Frontends/Clients etc. geben. Allein schon aus dieser Perspektive betrachtet, kann man erkennen, dass hier nicht zwingend ein Zusammenhang bestehen muss. Manchmal sind hier Ähnlichkeiten vorhanden, es gibt aber auch Fälle, in denen es Sinn macht, im Frontend mit den Micro Frontends einen ganz anderen Schnitt zu machen als im Umfeld der Micro Services.

Manfred: Im Zuge des Zusammenspiels von Micro Frontends und Micro Services ist immer wieder von einem Backend for Frontend, kurz BFF, die Rede. Was ist das und wann verwendet man sowas?

Daniel: Ein Backend for Frontend ist aus meiner Sicht ein Buttler für ein (Micro-)Frontend. Es kennt die Bedürfnisse des Frontends und ist das optimale Gegenstück dazu auf der Backendseite. Die Aufgaben, die ein BFF für ein Frontend übernehmen kann, sind sehr vielfältig.

Ein wichtiges Merkmal im Umfeld einer Micro Service Architektur sind das Aggregieren der Daten aus mehreren Micro Services, damit ein Frontend sich die Daten nicht selbst von vielen verschiedenen Micro Services zusammensuchen muss. Diese Aufgabe ist in der Regel mit den Werkzeugen, die wir auf Backendseite zu Verfügung haben einfacher und besser umzusetzen.

Weitere Merkmale die man in ein BFF, von mir auch gern als API Gateway bezeichnet, einbauen kann sind: Authentifizierung, Autorisierung, Routing zu Microservices, Sammeln von Telemetriedaten, Erstellen von Hypermediadokumenten für echte RESTful APIs.

Wichtig ist mir noch anzumerken, dass man aus meiner Sicht, möchte man eine Single Page Application bauen, das bestmögliche Ergebnis nur unter Zuhilfenahme eines BFFs erreicht werden kann.

Manfred: Du hast das Thema Authentifizierung erwähnt. Welche Möglichkeiten hat man, um sich bei einer Web API zu authentifizieren?

Daniel: Der de facto Standard der heute hier vorherrscht sind Token basierte Authentifizierungsmechanismen, nach den Standards OAuth 2 und OpenId Connect. Weit verbreitet ist noch, dass ein Client ein Token von einem Authorization Server anfragt und dies dann zur Authentifizierung am BFF verwendet. Neuerdings geht der Trend aber wieder dahin, dem Client nur ein http-only Cookie zu geben und das Token komplett serverseitig zu verwalten um die größtmögliche Sicherheit zu gewährleisten.

Dann bekommt das BFF eine weitere Aufgabe, nämlich das Token selbst anzufragen, zu cachen, und dem Client dann ein Cookie auszustellen.

Manfred: Ok, das war die Authentifizierung. Wie und wo findet die Autorisierung statt?

Daniel: Die Autorisierung ist immer sehr unterschiedlich umgesetzt, da sie auch sehr stark von den Anforderungen am Gesamtsystem abhängt. Es gibt sehr einfache Fälle -- da reicht es, wenn ein BFF in einem Token überprüft, ob für den aktuellen Benutzer im Token bestimmte Informationen vorhanden sind, z. B. ob dieser Schreib- oder doch nur Leserechte hat. In anderen Fällen muss die Autorisierung bis auf einzelne Datensätze abhängig von Benutzer und Geschäftsregeln entscheiden, ob eine bestimmte Operation an einem bestimmten Datensatz ausgeführt werden darf. Dann steckt die Logik der Autorisierung üblicherweise tief mit in der Business Logik verankert.

Manfred: In einem Atemzug mit Micro Services wird häufig DDD erwähnt. Was hat das eine mit dem anderen zu tun?

Daniel: Domain Driven Design ist eine super Herangehensweise, um unsere heutigen komplexen Systeme in Teilprobleme zu zerlegen. Dazu gibt uns DDD Methoden und Werkzeuge an die Hand, mit dessen Hilfe wir uns strukturiert und objektiv von den (Grob)Anforderungen an ein System bis zu dessen Schnitt vorarbeiten können.

Am Ende entstehen sogenannten Bounded Contexts -- dies sind voneinander abgegrenzte Lösungsbereiche, die sich jeweils um eines der Teilprobleme kümmern. Das besonders schöne ist, dass man am Ende meistens einfach sagen kann, jeder Bounded Context wird als ein eigener Microservice umgesetzt. Somit lässt DDD, das ja seine Ursprünge schon vor ca. 20 Jahren hatte, wunderbar mit heuten architekturellen Konzepten umsetzen.

DDD kann aber nicht nur helfen um ein Gesamtsystem zu schneiden, DDD kann auch dabei helfen saubere WebAPI Endpunkte zu entwickeln, die immer auf sogenannten Aggregaten Arbeiten, die durch DDD definiert werden.

Manfred: Wie komme ich zu einem guten Domänen-Schnitt?

Daniel: Das ist tatsächlich ein sehr anspruchsvoller Schritt beim Design einer neuen Architektur/ eines neuen Systems. Und vor allem ist es etwas, dass man üblicherweise nicht alle Tage macht. Somit hat man auch kaum Übung in dieser Tätigkeit. Daher ist es hier aus meiner Sicht immer zu empfehlen, sich bei diesem Schritt von Architekten unterstützen zu lassen, die in dieser Tätigkeit über Erfahrungen verfügen.

Da ich selbst auch eine Ausbildung als Agile Coach habe, verwende ich dafür auch viele Methoden aus dem Bereich der Agilen Entwicklungsmethoden, die ich mit DDD verbinde. Ich starte typischerweise damit, Epics und Personas zu definieren um ein Ziel aufzustellen. Danach folgt ein Event Storming Workshop. Innerhalb des Event Storms versuche ich dann erste Schnitte anhand von objektiven Kriterien wie, Kopplung von Daten und Funktionen oder pivotalen Ereignissen zu identifizieren.

Es folgt dann die Anwendung der Methoden aus DDD. Ich zeichne eine erste Context Map und wir verproben die Context Map in der Theorie gegen unseren Event Storm. Wenn etwas nicht funktioniert, wird entweder der Event Storm oder die Context Map angepasst. Dies kann sich einige Male wiederholen. Geschafft haben wir es, wenn die Context Map bei jedem ein gutes Gefühl hervorruft. Dann stehen auf der Context Map die benötigten Bounded Contexts und deren Abhängigkeiten zueinander.

Manfred: Das hört sich spannend an. Nun ergeben sich aus den Bounde Contexts häufig eigene Micro Services. Wie kommunizieren die untereinander?

Daniel: Hier haben wir eine ganze Reihe verschiedenster Technologien zur Auswahl. Die wichtigsten sind wohl: HTTP für synchrone Kommunikation, Message und Event Bus Systeme wie zum Beispiel RabbitMQ für asynchrone Kommunikation und wenn es mal ganz performant sein muss oder auch größere binäre Daten übertragen werden müssen könnte man auf gRPC zurückgreifen.

Mehr hierzu: Server Woche 🔥

Mehr zu Themen wie ✅ Micro Services, ✅ REST APIs ✅ DDD und ✅ modern Authentication erfährst Du in unserer Server-Woche, in der wir unsere Geschichte rund um Frontend-Architekturen im Backend "zu ende erzählen":

 

Daniel Murrmann beschäftigt sich seit Jahren mit Software Engineering sowie mit der Architektur und Umsetzung komplexer verteilter Software-Systeme im Industrie-Umfeld. Dabei setzt der studierte Informatiker und zertifizierte Software-Architekt im Frontend auf Angular. Außerdem konnte Daniel Erfahrung bei mehreren namhaften Konzernen sammeln und war unter anderem für ein großes Industrie-4.0-Projekt, das auch Angular im Frontend genutzt hat, bei einer deutschen Maschinenfabrik verantwortlich.

Daniel Murrmann