Das BFF - Der Leim der Backend&Frontend in Cloud-native Umgebungen zusammenhält

Wir haben es geschafft! Gemeinsam mit unserem Kunden stossen wir auf die erfolgreich aufgebaute Cloud-native Applikation auf Azure an.

Sie ist perfekt angelaufen und durch die verschiedenen Cloud Produkte, die genutzt wurden, konnten wir mit wenig Aufwand eine sichere und stabile Infrastruktur aufsetzen. Der Kunde ist begeistert und wir sind auch glücklich. Doch das war nicht immer so. Schaudernd denke ich an die Phase des Projekts zurück, in der unser Frontend und das Backend auseinanderzubrechen drohten.

Autorin: Dominique Heyn

Das Backend ist vollständig in der Cloud gehostet. Mit dem Frontend müssen wir aber die Cloud-native Umgebung verlassen: Die Browser, über die unsere Nutzer auf unsere App zugreifen, sind nicht Teil der Cloud-Infrastruktur und das bringt einige Herausforderungen mit sich. Wie erhält der Nutzer beispielsweise die nötigen Credentials und Informationen, um auf alle relevanten Backend Systeme zuzugreifen? Und wie schaffen wir es, das Frontend in den Rest der Infrastruktur zu integrieren?

Müssen wir unsere Party absagen oder schaffen wir es, ein Backend for Frontend (BFF) aufzubauen, das als Leim zwischen dem Frontend und dem Backend wirkt und die beiden Komponenten zu besten Freunden macht? Im Folgenden schauen wir uns an, was ein BFF ist, was es für Vorteile mit sich bringt und wie ein Frontend mithilfe eines BFFs in eine Cloud-native Architektur integriert werden kann.

Was ist ein BFF?

Ein BFF ist ein dünner Backend-Layer, das zwischen dem Backend und dem Frontend steht. Seine Hauptaufgabe ist es, Daten aus Backend Systemen zu aggregieren, zu filtern und dem Frontend in dem Format zur Verfügung zu stellen, welches das Frontend benötigt.

Datenfluss in einer Architektur mit Frontend, BFF und mehreren Backends
Abb 1: Datenfluss in einer Architektur mit Frontend, BFF und mehreren Backends

Die Grafik zeigt den Fluss von Daten in einer Architektur mit einem Frontend, einem BFF und mehreren Backends, die Daten zur Verfügung stellen.

  1. Alles beginnt mit einem Nutzer, der das Frontend in seinem Browser aufruft, um dort Daten einzusehen. Das Frontend schickt einen Request an das BFF, welches in der Cloud gehostet ist. Das BFF entscheidet anhand des eingehenden Requests, aus welchen Backend Systemen diese Daten angefragt werden.
  2. Anschliessend ruft das BFF die entsprechenden Backends auf. Diese sind ebenfalls in der Cloud gehostet.
  3. Das BFF formatiert und filtert die Daten.
  4. Im letzten Schritt werden die Daten an das Frontend und den Nutzer zurückgegeben.

Die Stärke des BFFs steckt hierbei im Schritt (3). Insbesondere bei komplexen Architekturen ist das Format der Daten aus den Backend Systemen häufig nicht das Format, das der Nutzer benötigt. Da das BFF explizit für das Frontend gebaut ist, kennt es das Datenformat des Frontends und kann die Daten dementsprechend strukturieren.

Zudem authentifiziert sich der Nutzer gegenüber dem BFF mit seinen persönlichen Credentials, beispielsweise mit dem OAuth Authorization Code Flow. Basierend auf den Rechten, die der Nutzer hat, kann das BFF weiter einschränken, welche Backend Systeme angefragt werden und die Daten dementsprechend filtern, bevor sie dem Nutzer zur Verfügung gestellt werden.
Damit wird der Datenschutz gewahrt und die Netzwerkbandbreite geschont. Um die Last auf die Backend Systeme zu reduzieren, kann das BFF Daten cachen, die eine lange Lebensdauer haben und so die Wartezeit im Frontend weiter verkürzen.

Einsatz in Cloud-native Applikationen

BFFs werden seit einigen Jahren eingesetzt. Mit der Verbreitung von Cloud-native Applikationen gewinnen sie immer mehr an Bedeutung, da sie dort die Integration des Frontends in die Cloud-native Umgebung übernehmen.

Beispielsweise ist das BFF Teil der Cloud-Infrastruktur und kann daher, wie die Backend Systeme, auf Managed Services in der Cloud zugreifen.

Schauen wir uns anhand des Authentifikations-Prozesses an, was dies für Vorteile bringt:

Das BFF entscheidet anhand des eingehenden Requests, welche Backend-Systeme aufgerufen werden. Es benötigt zwei fundamentale Informationen, um Anfragen an das Backend schicken zu können:

  1. Die URL des Backends
  2. und die Credentials, um sich ihm gegenüber zu authentifizieren

In einer Cloud-native Architektur werden diese Informationen in Managed Services gespeichert. Beispielsweise werden die URLs in einer App.Config gespeichert und Secrets, wie beispielsweise Credentials, in einem Key Vault.

Beim Aufsetzen des BFFs wird dem BFF eine Managed Identity zugewiesen, die Zugriff auf die Managed Services erhält. Mit der Managed Identity werden Konfigurationen und Secrets, sowie technische Nutzer und deren Passwörter verwaltet, ohne dass Anwender oder Administratoren mit ihnen interagieren müssen. Somit müssen sich Nutzer weniger Passwörter merken und Administratoren haben keinen Aufwand mehr damit, Passwörter von technischen Nutzern zu rotieren.

Hätten wir kein BFF im Einsatz, müssten die Informationen, die benötigt werden, um die entsprechenden Backends aufzurufen, im Frontend gespeichert werden und wären somit für den Nutzer einsehbar. Dies ist insbesondere für Credentials absolut tabu, da sie damit öffentlich zugänglich wären. Alternativ könnten sich die Nutzer mit ihren persönlichen Credentials gegenüber den Backends authentifizieren. Doch auch das ist nicht ideal, da in diesem Fall jeder Nutzer eine Rolle hätte für jedes Backend, auf das er zugreifen darf. Diese Vielzahl an Rollen muss gepflegt werden und bedeutet viel Aufwand.

Mit BFF hat der Nutzer eine Rolle für das BFF, die entscheidet, auf welche Backends der Nutzer zugreifen darf. Das BFF hat die entsprechenden Rollen der Backends und damit den notwendigen Zugriff. Dadurch werden den Nutzern weniger Rollen zugewiesen und weniger Rollen müssen gepflegt werden, ohne dass Sicherheits-Einbussen in Kauf genommen werden.

Authentifizierungs-Prozess mit einem BFF
Abb 2. Authentifizierungs-Prozess mit einem BFF

Konkret verläuft der Authentifizierungs-Prozess mit einem BFF wie in dieser Grafik.

  1. Der Nutzer authentifiziert sich gegenüber dem BFF mit dem OAuth Authorization Code Flow und seinen persönlichen Nutzerrollen. Das BFF kennt diese Nutzerrollen und weiss, auf welche Backends und Daten ein Nutzer mit diesen Rollen zugreifen darf.
  2. Das BFF holt sich die Konfigurationen, die es benötigt, um auf die relevanten Backend Systeme zuzugreifen, aus seiner App Config und seine OAuth Credentials aus seinem Key Vault.
  3. Das BFF ruft die Backend Systeme auf. Es hat dafür die App Roles der Backend Systeme und nutzt den OAuth Client Credentials Flow mit den Secrets aus Schritt (2), um sich gegenüber den Backend Systemen zu authentifizieren.
  4. Wie zuvor aggregiert, filtert und formatiert das BFF die Daten, die es von den Backends erhalten hat
  5. und gibt sie an das Frontend und den Nutzer zurück.

Der einfache Authentifikationsprozess ist nur ein Vorteil von Cloud Native Aspekten, die Dank des BFFs auch dem Frontend zur Verfügung stehen.

Ein weiteres Beispiel ist, dass das BFF unter der gleichen Domain wie das Frontend deployed werden kann. Damit entfallen aufwändige Cross-Origin-Resource-Sharing (CORS) Konfigurationen. CORS Policies kontrollieren die Quellen, von denen eine Website Inhalte laden kann. Damit wird verhindert, dass auf Inhalte ohne das Wissen des Nutzers von externen und potenziell bösartigen Quellen zugegriffen werden kann.

 

Trotz der vielen Vorteile kommt ein BFF natürlich nicht gratis. Es ist ein weiterer Infrastruktur-Layer, der unterhalten werden muss. In grossen Projekten, in denen verschiedene Teams für die Frontend- und Backend-Applikationen zuständig sind, empfiehlt es sich, dass das Frontend-Team das BFF entwickelt und unterhält. Damit wird sichergestellt, dass das BFF genau auf das Frontend zugeschnitten ist. Applikationslogik muss dabei aber weiterhin strikt im Backend bleiben. Für Datenaggregation, Authentifizierung und Integration ist das BFF der ideale Ort und kann an diesen Punkten seine volle Stärke entfalten.

Fazit

Ein BFF gibt feingranulare Kontrolle darüber wem welche Daten in welchem Format an das Frontend gegeben werden. Ursprünglich wurden BFFs häufig vor allem dann verwendet, wenn ein Backend-System für mehrere Frontends eingesetzt wurde. Pro Frontend wird in diesem Fall ein BFF aufgesetzt, das die Daten 1:1 in dem Format weitergibt, wie es das jeweilige Frontend benötigt.

Insbesondere in Cloud-native Architekturen ist das BFF auch in Szenarien sinnvoll, in denen es nur ein Frontend gibt. Es übernimmt die Integration des Frontends in eine Cloud-native Architektur, indem es beispielsweise erlaubt, Konfigurationen und Secrets sicher zu speichern. Das BFF macht es den Entwicklern leichter, das volle Potential von Cloud-Angeboten an den Nutzer weiterzugeben.

Für uns und unserem Kunden bedeutet dies, die Release Party kann natürlich weiter steigen und die nächste Runde Gingerbeer und Pizza ist auf dem Weg. 🥳

Weitere Quellen zu diesem Thema:

Sam Newman - BFF patterns

DominiqueHeyn_casual.jpg

Über mich

Als Full-stack Entwicklerin arbeite ich an Stellen, an denen Bereiche der Software Entwicklung aufeinander treffen. Dort ermöglicht eine gute Integration unseren Kunden eine ideale Digital Experience.