Decouple Back-End-Dienste von den Frontend-Implementierungen, um Oberflächen für verschiedene Clientschnittstellen anzupassen. Dieses Muster ist nützlich, wenn Sie vermeiden möchten, ein Back-End anzupassen, das mehrere Schnittstellen bedient. Dieses Muster basiert auf Pattern: Back-Ends for Frontends beschrieben von Sam Newman.
Kontext und Problem
Betrachten Sie eine Anwendung, die ursprünglich mit einer Desktopweb-UI und einem entsprechenden Back-End-Dienst entworfen wurde. Da sich die Geschäftlichen Anforderungen im Laufe der Zeit geändert haben, wurde eine mobile Schnittstelle hinzugefügt. Beide Schnittstellen interagieren mit demselben Back-End-Dienst, aber die Funktionen eines mobilen Geräts unterscheiden sich erheblich von einem Desktopbrowser in Bezug auf Bildschirmgröße, Leistung und Anzeigeeinschränkungen.
Der Back-End-Dienst steht häufig vor konkurrierenden Anforderungen verschiedener Frontends, was zu häufigen Änderungen und potenziellen Engpässen im Entwicklungsprozess führt. Widersprüchliche Updates und die Notwendigkeit der Kompatibilität führen zu übermäßiger Arbeit an einer einzelnen bereitstellungsfähigen Ressource.
Wenn ein separates Team den Back-End-Dienst verwaltet, kann eine Verbindung zwischen Frontend- und Back-End-Teams erstellt werden, was zu Verzögerungen bei der Gewinnung von Konsens- und Ausgleichsanforderungen führt. Beispielsweise müssen änderungen, die von einem Frontend-Team angefordert werden, vor der Integration mit anderen Frontend-Teams überprüft werden.
Lösung
Führen Sie eine neue Ebene ein, die nur die schnittstellenspezifischen Anforderungen behandelt. Diese Ebene, die als Back-End-for-Frontend-Dienst (BFF) bezeichnet wird, befindet sich zwischen dem Frontend-Client und dem Back-End-Dienst. Wenn die Anwendung mehrere Schnittstellen unterstützt, erstellen Sie einen BFF-Dienst für jede Schnittstelle. Wenn Sie beispielsweise über eine Webschnittstelle und eine mobile App verfügen, erstellen Sie jeweils separate BFF-Dienste.For example, if you have a web interface and a mobile app, you would create separate BFF services for each.
Dieses Muster passt die Clientumgebung auf eine bestimmte Schnittstelle an, ohne dass sich dies auf andere Schnittstellen auswirkt. Außerdem wird die Leistung optimal auf die Anforderungen der Front-End-Umgebung abgestimmt. Da jeder BFF-Dienst kleiner und weniger komplex ist, kann die Anwendung zu Optimierungsvorteilen in einem bestimmten Grad führen.
Front-End-Teams haben Autonomie gegenüber ihrem eigenen BFF-Dienst, sodass Flexibilität bei der Sprachauswahl, Der Veröffentlichungsrhythmen, der Workloadpriorisierung und der Featureintegration ermöglicht wird, ohne sich auf ein zentrales Back-End-Entwicklungsteam zu verlassen.
Während viele BFFs auf REST-APIs angewiesen sind, werden GraphQL-Implementierungen zu einer Alternative, wodurch die Notwendigkeit der BFF-Ebene entfernt wird, da der Abfragemechanismus keinen separaten Endpunkt erfordert.
Weitere Informationen finden Sie unter Pattern: Back-Ends for Frontends.
Probleme und Überlegungen
Bewerten Sie, was die optimale Anzahl von Diensten für Sie ist, da dies kostenaufwendte. Die Wartung und Bereitstellung weiterer Dienste bedeutet einen erhöhten Betriebsaufwand. Jeder einzelne Dienst verfügt über einen eigenen Lebenszyklus, Bereitstellungs- und Wartungsanforderungen und Sicherheitsanforderungen.
Überprüfen Sie beim Hinzufügen eines neuen Diensts die Ziele auf Dienstebene (Service Level Objectives, SLOs). Es kann zu einer erhöhten Latenz kommen, da Clients ihre Dienste nicht direkt kontaktieren, und der neue Dienst führt einen zusätzlichen Netzwerkhüpfpunkt ein.
Wenn unterschiedliche Schnittstellen dieselben Anforderungen stellen, bewerten Sie, ob die Anforderungen in einen einzigen BFF-Dienst konsolidiert werden können. Die Gemeinsame Nutzung eines einzelnen BFF-Diensts zwischen mehreren Schnittstellen kann zu unterschiedlichen Anforderungen für jeden Client führen, was das Wachstum und die Unterstützung des BFF-Diensts erschweren kann.
Die Codeduplizierung ist ein wahrscheinliches Ergebnis dieses Musters. Bewerten Sie den Kompromiss zwischen Codeduplizierung und einer besser angepassten Erfahrung für jeden Client.
Der BFF-Dienst sollte nur clientspezifische Logik im Zusammenhang mit einer bestimmten Benutzeroberfläche verarbeiten. Querschnittsfeatures wie Überwachung und Autorisierung sollten abstrahiert werden, um BFF Service Light zu halten. Typische Features, die im BFF-Dienst möglicherweise separat mit Gatekeeping, Rate Limiting, Routingund anderen behandelt werden.
Berücksichtigen Sie beim Erlernen und Implementieren dieses Musters die Auswirkungen auf das Entwicklungsteam. Das Erstellen neuer Back-Ends erfordert Zeit und Aufwand, was möglicherweise technische Schulden verursacht, während der bestehende Back-End-Dienst beibehalten wird.
Bewerten Sie, ob Sie dieses Muster überhaupt benötigen. Wenn Ihre Organisation beispielsweise GraphQL mit frontendspezifischen Resolvern verwendet, kann BFF Ihren Anwendungen möglicherweise keinen Mehrwert hinzufügen.
Ein weiteres Beispiel ist die Anwendung, die API-Gateway- mit Microservices kombiniert. Dieser Ansatz kann für einige Fälle ausreichen, in denen BFFs zuvor empfohlen wurden.
Wann dieses Muster verwendet werden soll
Verwenden Sie dieses Muster in folgenden Fällen:
Ein gemeinsam genutzter oder allgemeiner Back-End-Dienst muss mit erheblichem Entwicklungsaufwand verwaltet werden.
Sie möchten das Back-End für die Anforderungen bestimmter Clientschnittstellen optimieren.
Anpassungen werden an einem allgemeinen Back-End vorgenommen, um mehrere Schnittstellen zu berücksichtigen.
Eine Programmiersprache eignet sich besser für das Back-End einer bestimmten Benutzeroberfläche, aber nicht für alle Benutzeroberflächen.
Dieses Muster ist in folgenden Fällen unter Umständen nicht geeignet:
Wenn Schnittstellen dieselben oder ähnliche Anforderungen an das Back-End stellen.
Wenn nur eine Schnittstelle für die Interaktion mit dem Back-End verwendet wird.
Workloadentwurf
Ein Architekt sollte bewerten, wie das Back-Ends für Frontends-Muster im Design ihrer Workload verwendet werden kann, um die Ziele und Prinzipien zu erfüllen, die in den Azure Well-Architected Framework-Säulenbehandelt werden. Beispiel:
Säule | So unterstützt dieses Muster die Säulenziele |
---|---|
Zuverlässigkeitsdesignentscheidungen tragen dazu bei, dass Ihre Workload ausfallsicher wird und dass sie nach einem Ausfall wieder in einen voll funktionsfähigen Zustand zurückkehrt. | Separate Dienste, die exklusiv für eine bestimmte Frontend-Schnittstelle sind, enthalten Fehlfunktionen, sodass sich die Verfügbarkeit eines Clients möglicherweise nicht auf die Verfügbarkeit des Zugriffs eines anderen Clients auswirkt. Wenn Sie verschiedene Clients unterschiedlich behandeln, können Sie auch Zuverlässigkeitsbemühungen basierend auf erwarteten Clientzugriffsmustern priorisieren. - RE:02 Kritische Flows - RE:07 Selbsterhaltung |
Sicherheitsdesignentscheidungen tragen dazu bei, die Vertraulichkeit, Integrität und Verfügbarkeit der Daten und Systeme Ihrer Workload sicherzustellen. | Aufgrund der in diesem Muster eingeführten Diensttrennung kann die Sicherheit und Autorisierung auf der Dienstebene, die einen Client unterstützt, auf die für diesen Client erforderliche Funktionalität angepasst werden, wodurch die Fläche einer API und lateraler Bewegungen zwischen verschiedenen Back-Ends reduziert werden kann, die unterschiedliche Funktionen verfügbar machen können. - SE:04 Segmentation - SE:08 Härtungsressourcen |
Die Leistungseffizienz hilft Ihrer Workload, Anforderungen effizient durch Optimierungen in Skalierung, Daten und Code zu erfüllen. | Die Back-End-Trennung ermöglicht es Ihnen, auf Arten zu optimieren, die möglicherweise nicht mit einer Ebene gemeinsam genutzter Dienste möglich sind. Wenn Sie einzelne Clients unterschiedlich behandeln, können Sie die Leistung für die Einschränkungen und Funktionen eines bestimmten Clients optimieren. - PE:02 Kapazitätsplanung - PE:09 Kritische Flüsse |
Berücksichtigen Sie wie bei jeder Designentscheidung alle Kompromisse im Hinblick auf die Ziele der anderen Säulen, die mit diesem Muster eingeführt werden könnten.
Beispiel
Dieses Beispiel zeigt einen Anwendungsfall für das Muster, in dem Sie über zwei unterschiedliche Clientanwendungen verfügen: eine mobile App und eine Desktopanwendung. Beide Clients interagieren mit einem Azure-API-Management (Datenebenengateway), das als Abstraktionsebene fungiert und häufig auftretende Probleme wie:
Autorisierungs- – Sicherstellen, dass nur überprüfte Identitäten mit den richtigen Zugriffstoken geschützte Ressourcen mithilfe der Azure API Management (APIM) mit Microsoft Entra ID aufrufen können.
Monitoring – Erfassen und Senden von Anforderungs- und Antwortdetails für Observability-Zwecke an Azure Monitor.
Anforderungszwischenspeicherung – Optimieren wiederholter Anforderungen durch Die Bereitstellung von Antworten aus dem Cache mithilfe integrierter APIM-Features.
Routing & Aggregation – Weiterleiten eingehender Anforderungen an das entsprechende Back-End für BFF-Dienste (Frontend).
Jeder Client verfügt über einen dedizierten BFF-Dienst, der als Azure-Funktion ausgeführt wird, die als Vermittler zwischen dem Gateway und den zugrunde liegenden Microservices dient. Diese clientspezifischen BFF sorgen für eine maßgeschneiderte Benutzeroberfläche für die Paginierung unter anderen Funktionen. Während die mobile App mehr bandbreitenbewusste Apps ist und die Leistung verbessert, aggregiert der Desktop mehrere Seiten in einer einzigen Anforderung, um eine umfassendere Benutzererfahrung zu erzielen.
Das Diagramm ist in vier verschiedene Abschnitte unterteilt, die den Fluss von Anforderungen, Authentifizierung, Überwachung und clientspezifischer Verarbeitung veranschaulichen. Auf der linken Seite initiieren zwei Clientgeräte Anforderungen: eine mobile Anwendung, die für eine bandbreiteneffiziente Benutzeroberfläche optimiert ist, und ein Webbrowser, der eine voll funktionsfähige Benutzeroberfläche bietet. Pfeile reichen von beiden Geräten bis zum zentralen Einstiegspunkt, der das Azure API-Verwaltungsgateway ist und angibt, dass alle Anforderungen diese Ebene durchlaufen müssen. Innerhalb des zweiten Abschnitts, eingeschlossen in ein gestricheltes Linienrechteck, wird die Architektur in zwei horizontale Gruppen unterteilt. Die linke Gruppe stellt die Azure-API-Verwaltung dar, die für die Verarbeitung eingehender Anforderungen und die Bestimmung der Verarbeitung von eingehenden Anforderungen verantwortlich ist. Zwei Pfeile erstrecken sich von diesem Datenebenengateway nach außen: ein Pfeil nach oben auf die Microsoft Entra-ID, die die Autorisierung verwaltet, und ein weiterer Pfeil nach unten auf Azure Monitor, der für die Protokollierung und Observierbarkeit verantwortlich ist. Darüber hinaus durchläuft ein Pfeil eine Schleife vom Gateway zum mobilen Client, die eine zwischengespeicherte Antwort darstellt, wenn eine identische Anforderung wiederholt wird, wodurch unnötige Verarbeitung reduziert wird. Die richtige Gruppe innerhalb des gestrichelten Rechtecks konzentriert sich auf das Anpassen von Back-End-Antworten basierend auf dem Typ des Clients, der die Anforderung stellt. Es verfügt über zwei separate Back-End-für-Frontend-Clients, die beide mit Azure-Funktionen für serverloses Computing gehostet werden – eines, das dem mobilen Client und dem anderen dem Desktopclient zugeordnet ist. Zwei Pfeile reichen vom Gateway bis zu diesen Back-End-for-Frontend-Clients und zeigen, dass jede eingehende Anforderung je nach Clienttyp an den entsprechenden Dienst weitergeleitet wird. Über diese Ebene hinaus erweitern sich gestrichelte Pfeile weiter nach rechts und verbinden die Back-End-for-Frontend-Clients mit verschiedenen Microservices, die die eigentliche Geschäftslogik verarbeiten. Um dieses Diagramm zu visualisieren, stellen Sie sich einen Links-nach-rechts-Fluss vor, bei dem Clientanforderungen von mobilen und Webclients zum Gateway wechseln. Dieses Gateway verarbeitet jede Anforderung, während die Authentifizierung nach oben an den Identitätsanbieter delegiert und sich nach unten an den Überwachungsdienst anmeldet. Von dort aus leitet sie Anforderungen an den entsprechenden Back-End-for-Frontend-Client weiter, je nachdem, ob die Anforderung von einem Mobilen oder Desktopclient stammt. Schließlich leitet jeder Back-end-for-Frontend-Client die Anforderung an spezialisierte Microservices weiter, die die erforderliche Geschäftslogik ausführt und die erforderliche Antwort zurückgibt. Wenn eine zwischengespeicherte Antwort verfügbar ist, fängt das Gateway die Anforderung ab und sendet die gespeicherte Antwort direkt an den mobilen Client, um redundante Verarbeitung zu verhindern.
Ablauf A: Mobiler Client – Anforderung der ersten Seite
- Der mobile Client sendet eine
GET
Anforderung für die Seite1
einschließlich des OAuth 2.0-Tokens im Autorisierungsheader. - Die Anforderung erreicht das Azure APIM-Gateway, das es abfangen und:
- Überprüft den Autorisierungsstatus – APIM implementiert die Verteidigung im Detail, sodass sie die Gültigkeit des Zugriffstokens überprüft.
- Streamen Sie die Anforderungsaktivität als Protokolle an Azure Monitor – Details der Anforderung werden zur Überwachung und Überwachung aufgezeichnet.
- Die Richtlinien werden erzwungen, dann leitet Azure APIM die Anforderung an azure Function Mobile BFF weiter.
- Der Azure Function Mobile BFF interagiert dann mit den erforderlichen Microservices, um eine einzelne Seite abzurufen und die angeforderten Daten zu verarbeiten, um eine einfache Erfahrung zu bieten.
- Die Antwort wird an den Client zurückgegeben.
Ablauf B: Mobiler Client – Zwischengespeicherte Anforderung der ersten Seite
- Der mobile Client sendet dieselbe
GET
Anforderung für die Seite1
erneut, einschließlich des OAuth 2.0-Tokens im Autorisierungsheader. - Das Azure APIM-Gateway erkennt, dass diese Anforderung vor und:
- Die Richtlinien werden erzwungen, und danach wird eine zwischengespeicherte Antwort identifiziert, die den Anforderungsparametern entspricht.
- Gibt die zwischengespeicherte Antwort sofort zurück, ohne dass die Anforderung an azure Function Mobile BFF weitergeleitet werden muss.
Flow C: Desktopclient – erste Anforderung
- Der Desktopclient sendet eine
GET
Anforderung zum ersten Mal, einschließlich des OAuth 2.0-Tokens im Autorisierungsheader. - Die Anforderung erreicht das Azure APIM-Gateway, bei dem ähnliche grenzüberschreitende Bedenken behandelt werden:
- Autorisierung – Tokenüberprüfung ist immer erforderlich.
- Streamen Sie die Anforderungsaktivität – Anforderungsdetails werden zur Observability aufgezeichnet.
- Nachdem alle Richtlinien erzwungen wurden, leitet Azure APIM die Anforderung an den Azure Function Desktop BFF weiter, der für die Verarbeitung von datenintensiver Anwendungsverarbeitung verantwortlich ist. Der Desktop BFF aggregiert mehrere Anforderungen mithilfe zugrunde liegenden Microservices-Aufrufe, bevor er mit einer Antwort auf mehrere Seiten auf den Client reagiert.
Entwurf
Microsoft Entra ID dient als cloudbasierter Identitätsanbieter, der maßgeschneiderte Zielgruppenansprüche sowohl für mobile als auch für Desktopclients ausgibt, die anschließend zur Autorisierung genutzt werden.
Azure API Management fungiert als Proxy zwischen den Clients und ihren BBFs, die einen Umkreis hinzufügen. Es ist mit Richtlinien konfiguriert, um die JSON-Webtoken (JWTs) zu validieren, wobei Anforderungen abgelehnt werden, die ohne ein Token eingehen oder die Ansprüche für den zielbasierten BFF nicht gültig sind. Darüber hinaus werden alle Aktivitätsprotokolle an Azure Monitor gestreamt.
Azure Monitor als zentrale Überwachungslösung fungiert und alle Aktivitätsprotokolle aggregiert, um eine umfassende, end-to-End-Observierbarkeit sicherzustellen.
Azure Functions ist eine serverlose Lösung, die BFF-Logik nahtlos über mehrere Endpunkte verfügbar macht, wodurch eine optimierte Entwicklung ermöglicht wird, der Infrastrukturaufwand reduziert und die Betriebskosten gesenkt werden.