Stellen wir vor, wir arbeiten an einem ganz frischen Projekt, quasi auf der grünen Wiese, und so langsam wird es doch ganz schön groß. Wie können wir es strukturieren?
In mehreren Projekte habe ich mit Entwicklern zusammengearbeitet, deren Antwort fast reflexartig war: Aufteilen in Microservices! Der Reflex hatte einen Grund: Sie hatten Erfahrungen mit einem Monolithen, der im Laufe der Jahre groß, schwerfällig und unübersichtlich geworden war. Änderungen konnten sie dann nur langsam umsetzen.
Und so kenne ich Projekte, in denen schon am Tag 1, lange bevor alle Anforderungen klar waren, von einem Architekten eine bestimmte Aufteilung empfohlen wurde.
Nur die Aufteilung in Micro- und Nanoservives bringt ihrer eigenen Probleme mit sich.
Die zusätzliche Kommunikation zieht auch zusätzliche Fehlerquellen nach sich. Und an sich triviale Änderungen müssen machmal jetzt an mehreren Services nachgezogen werden. Der ursprüngliche Vorteil, die getrennte „Deploybarbeit“, schlägt in das Gegenteil um: Für Update muss plötzlich mehrere Services in einer bestimmten Reihenfolge aktualisiert werden.
In der Diskussion darüber habe ich dann manchmal eine der Lebenslügen von Entwicklern gehört:
Wir machen und doch jetzt am Anfang genaue Gedanken über die Datenstrukturen und werden wie dann so schnell nicht ändern müssen.
Aber was ist die Alternative?
Wir können beispielsweise unsere Anwendung intern so strukturieren als ob Sie aus mehreren Microservices bestehen würde.
Leider gibt es dafür erstaunlich wenig Unterstützung. Die Tutorials auch auch die mir bekannten Bücher helfen da kaum weiter.
Im Spring Ecosystem hat sich das Team um Oliver Drothbaum Gedanken darum gemacht und eine Lösung entwickelt. Set Ende des Jahres 2023 ist diese aus dem Betastatus heraus jetzt ein offizielles Projekt: Spring Modulith.
In meinem letzten Spring-Projekt habe ich Spring Modulith eingeführt und kann es weiterempfehlen.
Zunächst einmal können wir damit überwachen dass die Modulstruktur eingehalten wird. Ein Unit-Test überprüft dafür das alle Module ausschließlich über klare Schnittstellen anderer Module aufrufen können, ganz so als ob eigene Microservices wären. Spring Modulith analysiert dazu auch die Beans.
Als Extra wird auch die Struktur dokumentiert als UML Grafik ausgegeben
Sehr schön ist auch dass wir im Integrationstests nur für ein Modul schreiben können, die Beans aus den anderen Modulen werden dann gar nicht instantiiert.
Mehr Informationen gibt es auf der Projektseite zu Spring Modulith.