Blog

Das monolithische Frontend in der Microservices-Architektur

Ruben Oostinga

Aktualisiert Oktober 22, 2025
10 Minuten

Wenn Sie eine Microservices-Architektur implementieren, sollten Sie die Dienste klein halten. Das sollte auch für das Frontend gelten. Wenn Sie das nicht tun, werden Sie die Vorteile von Microservices nur für die Backend-Dienste nutzen können. Eine einfache Lösung besteht darin, Ihre Anwendung in separate Frontends aufzuteilen. Wenn Sie ein großes monolithisches Frontend haben, das sich nicht einfach aufteilen lässt, müssen Sie darüber nachdenken, es zu verkleinern. Sie können das Frontend in einzelne Komponenten aufteilen, die unabhängig voneinander von verschiedenen Teams entwickelt werden.

Stellen Sie sich vor, Sie arbeiten in einem Unternehmen, das von einer monolithischen Architektur zu einer Microservices-Architektur wechselt. Die Anwendung, an der Sie arbeiten, ist eine große kundenorientierte Webanwendung. Sie haben vor kurzem einige in sich geschlossene Funktionen identifiziert und Microservices erstellt, um die einzelnen Funktionen bereitzustellen. Ihr ehemaliger Monolith wurde auf das Wesentliche reduziert, um die Benutzeroberfläche bereitzustellen, d.h. Ihr öffentlich zugängliches Web-Frontend. Dieser Microservice hat nur eine einzige Funktion, nämlich die Bereitstellung der Benutzeroberfläche. Er kann skaliert und getrennt von den anderen Backend-Diensten bereitgestellt werden. Sie sind mit der Umstellung zufrieden: Einzelne Dienste passen in Ihren Kopf, mehrere Teams können an verschiedenen Anwendungen arbeiten, und Sie sprechen auf Konferenzen über Ihre Erfahrungen mit der Umstellung. Allerdings sind Sie noch nicht ganz am Ziel: Das Frontend ist immer noch ein Monolith, der die verschiedenen Backends überspannt. Das bedeutet, dass Sie am Frontend immer noch einige der Probleme haben, die Sie vor der Umstellung auf Microservices hatten. Die Abbildung unten zeigt eine Vereinfachung der aktuellen Architektur.

Einzelnes Frontend

[pullquote]Mit einem monolithischen Frontend haben Sie nie die Flexibilität, teamübergreifend zu skalieren, wie es Microservices versprechen.[/pullquote] Backend-Teams können keinen Geschäftswert liefern, ohne dass das Frontend aktualisiert wird, denn eine API ohne Benutzeroberfläche bringt nicht viel. Mehr Backend-Teams bedeuten mehr neue Funktionen und damit mehr Druck auf das/die Frontend-Team(s), neue Funktionen zu integrieren. Um dies zu kompensieren, kann das Frontend-Team vergrößert werden oder es können mehrere Teams an demselben Projekt arbeiten. Da das Frontend immer noch in einem Durchgang bereitgestellt werden muss, können die Teams nicht unabhängig voneinander arbeiten. Änderungen müssen in dasselbe Projekt integriert werden und das gesamte Projekt muss getestet werden, da eine Änderung andere Funktionen beeinträchtigen kann. Eine andere Möglichkeit ist, dass die Backend-Teams ihre neuen Funktionen in das Frontend integrieren und eine Pull-Anfrage einreichen. Dies hilft bei der Arbeitsteilung, aber um dies effektiv zu tun, muss viel Wissen zwischen den Teams ausgetauscht werden, damit der Code konsistent und auf dem gleichen Qualitätsniveau ist. Dies würde im Grunde bedeuten, dass die Teams nicht unabhängig voneinander arbeiten. Mit einem monolithischen Frontend erhalten Sie nie die Flexibilität, über Teams hinweg zu skalieren, wie es von Microservices versprochen wird. Neben der fehlenden Skalierbarkeit gibt es auch den klassischen Overhead eines separaten Backend- und Frontend-Teams. Jedes Mal, wenn die API eines der Dienste geändert wird, muss das Frontend aktualisiert werden. Insbesondere wenn ein Dienst um eine neue Funktion erweitert wird, muss das Frontend aktualisiert werden, damit Ihre Kunden diese Funktion überhaupt nutzen können. Wenn Sie ein Frontend haben, das klein genug ist, kann es von einem Team gewartet werden, das auch für einen oder mehrere Dienste zuständig ist, die mit dem Frontend gekoppelt sind. Das bedeutet, dass es keinen Overhead bei der teamübergreifenden Kommunikation gibt. Aber da das Frontend und das Backend nicht unabhängig voneinander bearbeitet werden können, handelt es sich nicht wirklich um Microservices. Für eine Anwendung, die klein genug ist, um von einem einzigen Team gewartet zu werden, ist es wahrscheinlich eine gute Idee, auf Microservices zu verzichten. Wenn Sie zwar mehrere Teams an Ihrer Plattform arbeiten lassen, aber mehrere kleinere Frontend-Anwendungen haben, wäre das kein Problem. Jedes Frontend würde als Schnittstelle zu einem oder mehreren Diensten dienen. Jeder dieser Dienste hat seine eigene Persistenzschicht. Dies wird als vertikale Dekomposition bezeichnet. Siehe das Bild unten.

frontend-per-service

Wenn Sie Ihre Anwendung aufteilen, müssen Sie sicherstellen, dass Sie die richtige Aufteilung vornehmen, die die gleiche ist wie bei den Backend-Diensten. Zunächst müssen Sie die begrenzten Kontexte erkennen, in die Ihre Domäne aufgeteilt werden kann. Ein begrenzter Kontext ist eine Partition des Domänenmodells mit einer klaren Grenze. Innerhalb des Bounded Contexts besteht eine hohe Kopplung und zwischen verschiedenen Bounded Contexts eine geringe Kopplung. Diese begrenzten Kontexte werden auf Mikrodienste innerhalb Ihrer Anwendung abgebildet. Auf diese Weise ist auch die Kommunikation zwischen den Diensten begrenzt. Mit anderen Worten: Sie begrenzen Ihre API-Oberfläche. Dies wiederum begrenzt die Notwendigkeit, Änderungen an der API vorzunehmen, und sorgt für wirklich getrennt arbeitende Teams. Oft können Sie Ihre Webanwendung nicht in mehrere völlig separate Anwendungen aufteilen. Ein einheitliches Erscheinungsbild muss beibehalten werden und die Anwendung sollte sich wie eine einzige Anwendung verhalten. Allerdings sind die Anwendung und das Entwicklungsteam groß genug, um eine Microservices-Architektur zu rechtfertigen. Beispiele für solche großen kundenorientierten Anwendungen finden sich im Online-Handel, bei Nachrichten, sozialen Netzwerken oder anderen Online-Plattformen. Auch wenn eine vollständige Aufteilung Ihrer Anwendung vielleicht nicht möglich ist, könnten mehrere Teams an separaten Teilen des Frontends arbeiten, als ob es sich um völlig separate Anwendungen handeln würde. Anstatt Ihre Webanwendung komplett aufzuteilen, teilen Sie sie in Komponenten auf, die separat gepflegt werden können. Auf diese Weise führen Sie eine Art vertikale Dekomposition durch, während Sie immer noch eine einzige konsistente Webanwendung haben. Um dies zu erreichen, haben Sie mehrere Möglichkeiten.

Code teilen

Sie können Code gemeinsam nutzen, um sicherzustellen, dass das Erscheinungsbild der verschiedenen Frontends einheitlich ist. Allerdings riskieren Sie dann, dass Dienste über den gemeinsamen Code gekoppelt werden. Dies könnte sogar dazu führen, dass Sie nicht in der Lage sind, die Software getrennt einzusetzen und freizugeben. Außerdem ist eine gewisse Koordinierung des gemeinsamen Codes erforderlich. Wenn Sie Code gemeinsam nutzen wollen, ist es daher in der Regel eine gute Idee, sich Gedanken über die API zu machen, die er bereitstellen soll. Ihre gemeinsam genutzte Bibliothek beispielsweise "common" zu nennen, ist im Allgemeinen eine schlechte Idee. Der Name suggeriert, dass Entwickler jeden Code, der von einem anderen Dienst gemeinsam genutzt werden kann, in die Bibliothek aufnehmen sollten. Common ist kein funktionaler Begriff, sondern ein technischer Begriff. Das bedeutet, dass sich die Bibliothek nicht darauf konzentriert, eine bestimmte Funktionalität bereitzustellen. Das Ergebnis ist eine API ohne ein bestimmtes Ziel, die sich häufig ändern wird. Dies ist besonders schlecht für Microservices, wenn mehrere Teams auf die neue Version migrieren müssen, wenn die API nicht mehr funktioniert. Obwohl die gemeinsame Nutzung von Code zwischen Microservices Nachteile hat, werden im Allgemeinen alle Microservices Code gemeinsam nutzen, indem sie Open Source-Bibliotheken verwenden. Da dieser Code immer von vielen Projekten verwendet wird, wird besonders darauf geachtet, dass die Kompatibilität nicht unterbrochen wird. Wenn Sie Code gemeinsam nutzen wollen, ist es eine gute Idee, den gemeinsam genutzten Code nach denselben Standards zu gestalten. Wenn Ihre Bibliothek nicht spezifisch für Ihr Unternehmen ist, können Sie sie auch öffentlich freigeben, um Sie zu ermutigen, zweimal darüber nachzudenken, ob Sie die API brechen oder geschäftsspezifische Logik in die Bibliothek einbauen.

Komposit-Frontend

Es ist möglich, Ihr Frontend aus verschiedenen Komponenten zusammenzustellen. Jede dieser Komponenten könnte von einem eigenen Team gepflegt und unabhängig voneinander eingesetzt werden. Auch hier ist es wichtig, die Komponenten entlang begrenzter Kontexte aufzuteilen, um die API-Oberfläche zwischen den Komponenten zu begrenzen. Die Abbildung unten zeigt ein Beispiel für ein solches zusammengesetztes Frontend.

Komposit-Design

Zugegebenermaßen ist dies eine Idee, die wir bereits in Portlets während des SOA-Zeitalters gesehen haben. In einer Microservices-Architektur möchten Sie jedoch, dass die Frontend-Komponenten völlig unabhängig voneinander eingesetzt werden können, und Sie möchten sicherstellen, dass Sie eine saubere Trennung vornehmen, die gewährleistet, dass keine oder nur eine begrenzte Zwei-Wege-Kommunikation zwischen den Komponenten erforderlich ist. Es ist möglich, während der Entwicklung, der Bereitstellung oder zur Laufzeit zu integrieren. In jeder dieser Integrationsphasen gibt es unterschiedliche Kompromisse zwischen Flexibilität und Konsistenz. Wenn Sie getrennte Bereitstellungspipelines für Ihre Komponenten haben möchten, sollten Sie einen flexibleren Ansatz wie die Integration zur Laufzeit wählen. Wenn es wahrscheinlicher ist, dass unterschiedliche Versionen von Komponenten die Funktionalität beeinträchtigen, benötigen Sie mehr Konsistenz. Diese würden Sie bei der Integration zur Entwicklungszeit erreichen. Die Integration zur Bereitstellungszeit könnte Ihnen die gleiche Flexibilität wie die Laufzeitintegration bieten, wenn Sie in der Lage sind, verschiedene Versionen von Komponenten in verschiedenen Umgebungen Ihrer Build-Pipeline zu integrieren. Dies würde jedoch bedeuten, dass Sie für jede Umgebung ein anderes Deployment-Artefakt erstellen müssten. [pullquote]Softwarearchitektur sollte nie ein Ziel sein, sondern ein Mittel zum Zweck[/pullquote] Die Kombination mehrerer Komponenten über gemeinsam genutzte Bibliotheken in einem einzigen Frontend ist ein Beispiel für die Integration in der Entwicklungszeit. Sie bietet Ihnen jedoch nicht viel Flexibilität in Bezug auf die separate Bereitstellung. Es handelt sich immer noch um eine klassische Integrationstechnik. Aber da die Softwarearchitektur nie ein Ziel, sondern ein Mittel zum Zweck sein sollte, kann sie die beste Lösung für das Problem sein, das Sie zu lösen versuchen. Mehr Flexibilität bietet die Integration zur Laufzeit. Ein Beispiel hierfür ist die Verwendung von AJAX zum Laden von HTML und anderen Abhängigkeiten einer Komponente. Dann muss die Hauptanwendung nur noch wissen, woher sie die Komponente abrufen soll. Dies ist ein gutes Beispiel für eine kleine API-Oberfläche. Natürlich bedeutet eine Anfrage nach dem Laden der Seite, dass die Benutzer sehen können, wie die Komponenten geladen werden. Es bedeutet auch, dass Clients, die kein Javascript ausführen, den Inhalt überhaupt nicht sehen. Beispiele dafür sind Bots/Spider, die kein Javascript ausführen, echte Benutzer, die Javascript blockieren oder einen Screenreader verwenden, der kein Javascript ausführt. Wenn die Laufzeitintegration über Javascript keine Option ist, ist es auch möglich, Komponenten über eine Middleware-Schicht zu integrieren. Diese Schicht holt die HTML-Daten der verschiedenen Komponenten ab und setzt sie zu einer vollständigen Seite zusammen, bevor sie die Seite an den Client zurückgibt. Das bedeutet, dass die Clients immer die gesamte HTML auf einmal abrufen. Ein Beispiel für eine solche Middleware sind die Edge Side Includes von Varnish. Um mehr Flexibilität zu erhalten, ist es auch möglich, einen Server, der dies tut, manuell zu implementieren. Ein Open Source-Beispiel für einen solchen Server ist Compoxure. Sobald Sie Ihr zusammengesetztes Frontend zum Laufen gebracht haben, können Sie über den nächsten Schritt nachdenken: die Optimierung. Wenn Sie separate Komponenten aus verschiedenen Quellen haben, bedeutet das, dass der Client viele Ressourcen abrufen muss. Da der Abruf mehrerer Ressourcen länger dauert als der Abruf einer einzelnen Ressource, sollten Sie die Ressourcen kombinieren. Auch dies kann zur Entwicklungszeit oder zur Laufzeit geschehen, je nachdem, welche Integrationstechniken Sie für die Dekomposition Ihres Frontends gewählt haben.

Fazit

Bei der Umstellung einer Anwendung auf eine Microservices-Architektur werden Sie auf Probleme stoßen, wenn Sie das Frontend als Monolith beibehalten. Das Ziel ist es, eine gute vertikale Dekomposition zu erreichen. Was für die Backend-Dienste gilt, gilt auch für das Frontend: Teilen Sie es in begrenzte Kontexte auf, um die API-Oberfläche zwischen den Komponenten zu begrenzen, und verwenden Sie Integrationstechniken, die eine Kopplung vermeiden. Wenn Sie an einem einzigen großen Frontend arbeiten, mag es schwierig sein, diese Aufteilung vorzunehmen, aber wenn Sie mit mehreren Teams, die an einer Microservices-Architektur arbeiten, schneller liefern wollen, können Sie das Frontend nicht von der Aufteilung ausschließen.

Ressourcen

Sam Newman - Von Makro zu Mikro: Wie groß sollten Ihre Dienste sein? Dan North - Microservices: Software, die in Ihren Kopf passt

Verfasst von

Ruben Oostinga

Contact

Let’s discuss how we can support your journey.