Comprendre le modèle Backend for Frontend (BFF) : un guide simple

Comprendre le modèle Backend for Frontend (BFF) : un guide simple

Dans une architecture de microservices, nos systèmes sont décomposés en dizaines de petits services ciblés, comme un service utilisateur, un service de commande et un service produit.

Mais lorsqu’il s’agit d’afficher ces informations à vos utilisateurs, les différents appareils ont des besoins très différents. Un navigateur Web sur un ordinateur de bureau à grande vitesse nécessite un tableau de bord riche rempli de tableaux, de barres latérales et de graphiques. Une application mobile sur un réseau cellulaire lent nécessite une mise en page simple et légère pour économiser la bande passante et la batterie. Une application de montre intelligente peut n’avoir besoin que d’une seule ligne de texte.

Si tous ces frontaux interrogent exactement la même API backend, quelqu’un doit faire un compromis. Soit l’application mobile est obligée de télécharger d’énormes quantités de données inutiles, soit l’application Web est obligée d’effectuer des dizaines de requêtes réseau distinctes pour récupérer tout ce dont elle a besoin.

C’est exactement le problème résolu par le modèle Backend for Frontend (BFF). Dans ce guide, nous expliquerons ce modèle avec des mots simples, examinerons une analogie du monde réel, le comparerons à une passerelle API standard et passerons en revue une implémentation pratique du code.


L’analogie avec le monde réel : le menu du restaurant

Imaginez un restaurant qui sert trois types de convives très différents :

  1. Un critique gastronomique qui souhaite un menu dégustation complet de 5 plats avec des listes d’ingrédients détaillées.
  2. Un navetteur occupé qui veut une collation rapide et préemballée à manger dans le train.
  3. Un enfant qui veut un repas simple avec de petites portions et sans ingrédients épicés.

Si le restaurant n’avait qu’un un seul menu répertoriant les trois options en détail, ce serait écrasant. Le navetteur perdrait du temps à lire des recettes à 5 plats et les parents de l’enfant auraient du mal à trouver des options alimentaires simples.

Au lieu de cela, le restaurant imprime trois menus personnalisés : un menu dégustation, un menu express à emporter et un menu pour enfants.

Chaque menu s’inspire de la même cuisine (les microservices), mais formate et dimensionne les choix spécifiquement pour ce client (le client).

Dans ce scénario :

  • La cuisine représente vos microservices (Utilisateur, Catalogue, Paiement).
  • Les menus personnalisés sont vos BFF (Web BFF, Mobile BFF, Watch BFF).
  • Les convives sont vos interfaces (navigateur de bureau, application mobile, montre intelligente).

Le problème : l’API « taille unique »

Lorsque les microservices sont devenus populaires, de nombreuses équipes ont créé une passerelle API unique et partagée pour gérer tous les clients frontaux :

Schéma d'architecture Backend for Frontend (BFF) comparant les flux Web et mobiles

Même si un point d’entrée unique est une bonne chose, une API partagée introduit plusieurs goulots d’étranglement en matière de mise à l’échelle :

  • Payload Bloat for Mobile : l’application Web de bureau a besoin de l’historique des commandes, de l’adresse de facturation, de la photo de profil et des points de fidélité de l’utilisateur. L’application mobile doit uniquement afficher « Dernière commande : expédiée ». Avec une API partagée, l’application mobile télécharge l’intégralité de la charge utile du profil, gaspillant ainsi de précieuses données et ralentissant les temps de chargement.
  • Glots d’étranglement API : une seule équipe devient le goulot d’étranglement de la passerelle partagée. Si l’équipe iOS souhaite modifier un petit champ de mise en page, elle doit attendre que l’équipe de la passerelle partagée déploie une nouvelle version, ce qui ralentit les cycles de développement.
  • Différents besoins de sécurité : un navigateur Web peut nécessiter des sessions basées sur des cookies pour empêcher le Cross-Site Scripting (XSS), alors qu’une application mobile préfère les en-têtes OAuth basés sur des jetons. La gestion des deux sur un seul serveur crée un code complexe et désordonné.

La solution : le modèle BFF

Au lieu de créer une passerelle géante pour tous les appareils, le BFF Pattern préconise la création d’un serveur backend dédié pour chaque application frontend.

Vous aurez :

  • Web BFF : gère les requêtes du navigateur de bureau. Il regroupe des profils complets, des catalogues de produits et des informations détaillées sur le paiement.
  • Mobile BFF : gère les demandes des applications iOS et Android. Il regroupe les données, filtre les champs inutiles et compresse la réponse finale pour garantir des performances rapides.

API Gateway vs BFF : quelle est la différence ?

Il est courant de confondre ces deux modèles car ils se situent tous deux entre le client et les microservices. Voici la distinction :

Fonctionnalité Passerelle API générale Backend pour Frontend (BFF)
Nombre de passerelles Généralement un pour l’ensemble du système. Multiple (un pour chaque type de périphérique client).
Responsabilité Routage de haut niveau, limitation de débit et sécurité globale. Agréger les données et adapter les charges utiles pour une interface spécifique.
Propriété Géré par une équipe dédiée à l’infrastructure backend/plateforme. Géré par l’équipe frontend qui crée l’application correspondante.
Personnalisation Faible. Les changements affectent tous les clients. Haut. Les modifications n’affectent qu’une seule application client.

Une implémentation pratique (Node.js/Express)

Pour comprendre comment cela fonctionne en pratique, écrivons un exemple simple de Node.js.

Imaginez que nous ayons deux microservices exécutés en interne :

  • Service utilisateur (renvoie les informations de base du profil utilisateur)
  • Service de commande (renvoie une liste de commandes avec tous les détails)

Nous souhaitons créer un Web BFF et un Mobile BFF pour servir différemment notre site de bureau et notre application mobile.

1. La simulation de microservices partagés

Tout d’abord, voici les données fictives de nos deux microservices sous-jacents :

// 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. Le Web BFF (renvoie la charge utile détaillée complète)

Le Web BFF regroupe tous les champs car l’écran du bureau dispose de suffisamment d’espace pour les afficher :

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. Le Mobile BFF (renvoie une charge utile minimisée et agrégée)

Le Mobile BFF filtre les champs inutiles (comme l’e-mail, les paramètres et les taxes) et regroupe les éléments de commande pour économiser de la bande passante :

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'));

Comparaison de la taille de la charge utile

  • Taille de réponse Web BFF : contient la configuration imbriquée, les préférences, la liste complète des commandes, les taxes, les articles, etc. (environ 400 octets).
  • Taille de réponse Mobile BFF : contient seulement 6 paires clé-valeur représentant l’essentiel. (Environ 120 octets – 70 % de réduction de la taille du réseau !).

Avantages et inconvénients du modèle BFF

Bien que très efficace, le modèle BFF comporte des compromis :

Avantage (Pro) Inconvénient (Con)
Performances client optimisées : les clients chargent uniquement les données exactes dont ils ont besoin, réduisant ainsi la consommation de la batterie et l’utilisation de la mémoire. Duplication de code : vous pourriez finir par écrire une logique de récupération de données similaire dans plusieurs bases de code BFF.
Cycles de publication plus rapides : L’équipe frontend mobile peut mettre à jour son serveur BFF sans avoir besoin de se coordonner avec les développeurs Web. Augmentation du nombre de serveurs : au lieu de gérer une seule passerelle API, vous devez désormais déployer et gérer plusieurs services BFF.
Code frontal simplifié : le client n’a pas besoin de gérer une logique complexe de tri, de filtrage ou de fusion ; il affiche simplement le JSON qu’il reçoit. Gestion de la sécurité : les certifications SSL/TLS, les règles de limite de débit et les pare-feu doivent être gérés sur plusieurs passerelles.

Conclusion

Le modèle Backend for Frontend (BFF) est une architecture puissante pour les systèmes qui servent plusieurs types de clients, tels que les appareils Web, mobiles et IoT. En créant des passerelles sur mesure pour chaque interface spécifique, vous découplez le développement client, minimisez la taille de la charge utile et offrez une expérience utilisateur plus rapide et plus réactive.

Si votre système ne dispose que d’une seule application Web, une passerelle API partagée est suffisante. Mais dès que vous commencez à créer des applications mobiles ou des expériences d’appareils spécialisés parallèlement à votre application Web, la mise en œuvre d’un BFF est le meilleur moyen de garder vos architectures frontend et backend propres, optimisées et indépendantes.


Découvrez davantage d’informations sur le développement logiciel et l’ingénierie back-end sur le blog Ghaznix →