Das Backend-for-Frontend-Muster (BFF) verstehen: Eine einfache Anleitung

Das Backend-for-Frontend-Muster (BFF) verstehen: Eine einfache Anleitung

In einer Microservices-Architektur sind unsere Systeme in Dutzende kleiner, fokussierter Services unterteilt – wie einen Benutzerservice, einen Bestellservice und einen Produktservice.

Wenn es jedoch darum geht, Ihren Benutzern diese Informationen anzuzeigen, haben verschiedene Geräte sehr unterschiedliche Anforderungen. Ein Webbrowser auf einem Hochgeschwindigkeits-Desktop-Computer benötigt ein umfangreiches Dashboard voller Tabellen, Seitenleisten und Grafiken. Eine mobile App in einem langsamen Mobilfunknetz benötigt ein einfaches, schlankes Layout, um Bandbreite und Akku zu sparen. Eine Smartwatch-App benötigt möglicherweise nur eine einzige Textzeile.

Wenn alle diese Frontends genau dieselbe Backend-API abfragen, muss jemand Kompromisse eingehen. Entweder ist die mobile App gezwungen, riesige Mengen nutzloser Daten herunterzuladen, oder die Web-App ist gezwungen, Dutzende separate Netzwerkanfragen zu stellen, um alles abzurufen, was sie benötigt.

Dies ist genau das Problem, das durch das Backend for Frontend (BFF) Pattern gelöst wird. In diesem Leitfaden erklären wir dieses Muster in einfachen Worten, betrachten eine Analogie aus der realen Welt, vergleichen es mit einem Standard-API-Gateway und gehen durch eine praktische Code-Implementierung.


Die Analogie zur realen Welt: Die Speisekarte des Restaurants

Stellen Sie sich ein Restaurant vor, das drei sehr unterschiedliche Arten von Gästen bedient:

  1. Ein Lebensmittelkritiker, der ein komplettes 5-Gänge-Degustationsmenü mit detaillierten Zutatenlisten möchte.
  2. Ein vielbeschäftigter Pendler, der im Zug einen schnellen, abgepackten Snack essen möchte.
  3. Ein Kind, das ein einfaches Kindergericht mit kleinen Portionen und ohne scharfe Zutaten möchte.

Wenn das Restaurant nur ein einziges Menü hätte, das alle drei Optionen detailliert auflistet, wäre es überwältigend. Der Pendler würde seine Zeit damit verschwenden, 5-Gänge-Rezepte durchzulesen, und die Eltern des Kindes hätten Schwierigkeiten, einfache Essensmöglichkeiten zu finden.

Stattdessen druckt das Restaurant drei benutzerdefinierte Menüs: ein Degustationsmenü, ein Express-To-Go-Menü und ein Kindermenü.

Jedes Menü basiert auf derselben Küche (den Microservices), formatiert und dimensioniert die Auswahl jedoch speziell für diesen Kunden (den Kunden).

In diesem Szenario:

  • Die Küche repräsentiert Ihre Mikroservices (Benutzer, Katalog, Zahlung).
  • Die benutzerdefinierten Menüs sind deine BFFs (Web-BFF, Mobile-BFF, Watch-BFF).
  • Die Gäste sind Ihre Frontends (Desktop-Browser, mobile App, Smartwatch).

Das Problem: Die „One-Size-Fits-All“-API

Als Microservices zum ersten Mal populär wurden, bauten viele Teams ein einziges, gemeinsames API-Gateway für die Verwaltung aller Frontend-Clients:

Backend for Frontend (BFF)-Architekturdiagramm zum Vergleich von Web- und Mobile-Flows

Während ein einzelner Einstiegspunkt großartig ist, führt eine gemeinsame API zu mehreren Skalierungsengpässen:

  • Payload Bloat for Mobile: Die Desktop-Web-App benötigt den Bestellverlauf, die Rechnungsadresse, das Profilbild und die Treuepunkte des Benutzers. In der mobilen App muss nur „Letzte Bestellung: Versandt“ angezeigt werden. Mit einer gemeinsamen API lädt die mobile App die gesamte Profilnutzlast herunter, wodurch wertvolle Daten verschwendet und die Ladezeiten verlangsamt werden.
  • API-Engpässe: Ein einzelnes Team wird zum Engpass für das gemeinsame Gateway. Wenn das iOS-Team ein kleines Layoutfeld ändern möchte, muss es warten, bis das Shared-Gateway-Team eine neue Version bereitstellt, was die Entwicklungszyklen verlangsamt.
  • Unterschiedliche Sicherheitsanforderungen: Ein Webbrowser erfordert möglicherweise Cookie-basierte Sitzungen, um Cross-Site Scripting (XSS) zu verhindern, während eine mobile App tokenbasierte OAuth-Header bevorzugt. Die Verarbeitung beider auf einem einzigen Server führt zu komplexem, chaotischem Code.

Die Lösung: Das BFF-Muster

Anstatt ein riesiges Gateway für alle Geräte zu erstellen, empfiehlt das BFF Pattern den Aufbau eines dedizierten Backend-Servers für jede Frontend-Anwendung.

Sie erhalten:

  • Web BFF: Verarbeitet Anfragen vom Desktop-Browser. Es fasst vollständige Profile, Produktkataloge und detaillierte Checkout-Informationen zusammen.
  • Mobile BFF: Verarbeitet Anfragen von iOS- und Android-Apps. Es aggregiert Daten, filtert unnötige Felder heraus und komprimiert die endgültige Antwort, um eine schnelle Leistung sicherzustellen.

API Gateway vs. BFF: Was ist der Unterschied?

Es kommt häufig vor, dass diese beiden Muster verwechselt werden, da sie beide zwischen dem Client und den Microservices angesiedelt sind. Hier ist der Unterschied:

Funktion Allgemeines API-Gateway Backend für Frontend (BFF)
Anzahl der Gateways Normalerweise eins für das gesamte System. Mehrere (eines für jeden Typ von Client-Gerät).
Verantwortung High-Level-Routing, Ratenbegrenzung und globale Sicherheit. Daten aggregieren und Nutzlasten für ein bestimmtes Frontend anpassen.
Eigentum Verwaltet von einem dedizierten Backend-/Plattform-Infrastrukturteam. Verwaltet vom Frontend-Team, das die entsprechende App erstellt.
Anpassung Niedrig. Änderungen wirken sich auf alle Clients aus. Hoch. Änderungen wirken sich nur auf eine Clientanwendung aus.

Eine praktische Implementierung (Node.js/Express)

Um zu verstehen, wie das in der Praxis funktioniert, schreiben wir ein einfaches Node.js-Beispiel.

Stellen Sie sich vor, wir haben zwei Microservices, die intern ausgeführt werden:

  • Benutzerdienst (gibt grundlegende Benutzerprofilinformationen zurück)
  • Bestellservice (gibt eine Liste der Bestellungen mit allen Details zurück)

Wir möchten eine Web-BFF und eine Mobile-BFF erstellen, um unsere Desktop-Site und unsere mobile App unterschiedlich zu bedienen.

1. Der Shared Microservices Mock

Hier sind zunächst die Scheindaten für unsere beiden zugrunde liegenden Microservices:

// Internal User Service Response
const userProfile = {
    id: 42,
    username: "dev_coder",
    email: "coder@ghaznix.com",
    avatarUrl: "https://ghaznix.com/avatars/42.png",
    preferences: { theme: "light", newsletter: true }
};

// Internal Order Service Response
const orderHistory = [
    { id: "ORD-99", date: "2026-06-25", items: ["Laptop", "Mouse"], status: "Shipped", tax: 15.00, total: 1215.00 },
    { id: "ORD-88", date: "2026-05-12", items: ["Keyboard"], status: "Delivered", tax: 5.00, total: 105.00 }
];

2. The Web BFF (gibt die vollständige, detaillierte Nutzlast zurück)

Die Web-BFF fasst alle Felder zusammen, da auf dem Desktop-Bildschirm ausreichend Platz für deren Anzeige vorhanden ist:

const express = require('express');
const webBff = express();

webBff.get('/dashboard', (req, res) => {
    // Web needs everything: profile + full order details + settings
    const responsePayload = {
        user: {
            username: userProfile.username,
            email: userProfile.email,
            avatar: userProfile.avatarUrl,
            theme: userProfile.preferences.theme
        },
        orders: orderHistory // Send all order details, taxes, and items
    };
    
    res.json(responsePayload);
});

webBff.listen(3001, () => console.log('Web BFF running on port 3001'));

3. Die mobile BFF (Retouren minimiert, aggregierte Nutzlast)

Das Mobile BFF filtert nicht benötigte Felder (wie E-Mail, Einstellungen und Steuern) heraus und aggregiert die Bestellelemente, um Bandbreite zu sparen:

const express = require('express');
const mobileBff = express();

mobileBff.get('/dashboard', (req, res) => {
    // Mobile only wants: username, avatar, and summary of the latest order
    const latestOrder = orderHistory[0];
    
    const responsePayload = {
        user: {
            username: userProfile.username,
            avatar: userProfile.avatarUrl
        },
        latestOrderStatus: {
            orderId: latestOrder.id,
            status: latestOrder.status,
            date: latestOrder.date,
            itemCount: latestOrder.items.length // Send count instead of array list
        }
    };
    
    res.json(responsePayload);
});

mobileBff.listen(3002, () => console.log('Mobile BFF running on port 3002'));

Nutzlastgrößenvergleich

  • Web-BFF-Antwortgröße: Enthält verschachtelte Konfiguration, Präferenzen, vollständige Bestellliste, Steuern, Artikel usw. (ca. 400 Byte).
  • Mobile BFF-Antwortgröße: Enthält nur 6 Schlüssel-Wert-Paare, die das Nötigste darstellen. (Ca. 120 Bytes – 70 % Reduzierung der Netzwerkgröße!).

Vor- und Nachteile des BFF-Musters

Das BFF-Muster ist zwar sehr effektiv, hat aber auch Nachteile:

Advantage (Pro) Nachteil (Kontra)
Optimierte Client-Leistung: Clients laden nur genau die Daten, die sie benötigen, wodurch der Batterieverbrauch und die Speichernutzung reduziert werden. Codeduplizierung: Am Ende schreiben Sie möglicherweise eine ähnliche Datenabruflogik in mehreren BFF-Codebasen.
Schnellere Veröffentlichungszyklen: Das mobile Frontend-Team kann seinen BFF-Server aktualisieren, ohne sich mit Webentwicklern abstimmen zu müssen. Erhöhte Serveranzahl: Anstatt ein API-Gateway zu verwalten, müssen Sie jetzt mehrere BFF-Dienste bereitstellen und verwalten.
Vereinfachter Frontend-Code: Der Client muss sich nicht mit komplexer Sortier-, Filter- oder Zusammenführungslogik befassen; Es zeigt nur den JSON an, den es empfängt. Sicherheitsmanagement: SSL/TLS-Zertifizierungen, Ratenbegrenzungsregeln und Firewalls müssen über mehrere Gateways hinweg verwaltet werden.

Abschluss

Das Backend for Frontend (BFF) Pattern ist eine leistungsstarke Architektur für Systeme, die mehrere Clienttypen bedienen, wie z. B. Web-, Mobil- und IoT-Geräte. Durch die Erstellung maßgeschneiderter Gateways für jedes spezifische Frontend entkoppeln Sie die Client-Entwicklung, minimieren die Nutzlastgröße und sorgen für ein schnelleres, reaktionsfähigeres Benutzererlebnis.

Wenn Ihr System nur über eine einzige Webanwendung verfügt, reicht ein gemeinsames API-Gateway aus. Aber sobald Sie mit der Entwicklung mobiler Apps oder spezieller Geräteerlebnisse neben Ihrer Webanwendung beginnen, ist die Implementierung eines BFF die beste Möglichkeit, Ihre Frontend- und Backend-Architekturen sauber, optimiert und unabhängig zu halten.


Weitere Einblicke in Softwareentwicklung und Backend-Engineering finden Sie im Ghaznix-Blog →