Le pattern Backend For Frontend, abrégé BFF, désigne une couche serveur dédiée à un seul type de client. Au lieu de laisser une application web ou mobile appeler directement une dizaine d'API et recoller les données elle-même, on intercale un service qui fait ce travail à sa place, dans le format exact dont elle a besoin. L'idée est née chez SoundCloud vers 2015, quand les équipes se sont rendu compte qu'une API unique ne pouvait pas satisfaire à la fois leur site web et leurs applications mobiles sans devenir un monstre impossible à faire évoluer.
Le BFF, c'est quoi concrètement
Prenez une application classique : un site web, une app iOS, une app Android, et derrière, une architecture en microservices — un service pour les comptes, un pour le catalogue, un pour les paiements, un pour les notifications. Sans BFF, chaque front-end doit connaître tous ces services, les appeler dans le bon ordre, agréger les réponses et les remettre en forme. Le navigateur passe son temps à orchestrer des appels réseau au lieu d'afficher l'interface.
Avec un BFF, le front-end ne parle plus qu'à un seul interlocuteur. Il envoie une requête, le BFF appelle les services dont il a besoin, assemble le résultat et renvoie une réponse taillée sur mesure. Le point important : un BFF par expérience client. Le BFF web et le BFF mobile ne renvoient pas la même chose, parce qu'un écran de smartphone n'a pas les mêmes besoins qu'un dashboard de bureau. L'app mobile veut une charge utile légère et déjà découpée pour un petit écran ; le web peut se permettre des données plus riches.
Le problème que ça résout
Trois douleurs reviennent systématiquement quand le front-end tape directement dans les API.
L'over-fetching et l'under-fetching : une API généraliste renvoie soit trop de données (le client télécharge un objet complet pour n'en afficher que trois champs), soit pas assez (il doit enchaîner plusieurs appels pour reconstituer un écran). Dans les deux cas, l'utilisateur attend. Le BFF renvoie exactement les champs de l'écran, ni plus ni moins.
Le couplage : quand le front-end connaît la structure de chaque microservice, la moindre modification d'une API côté back-end casse potentiellement l'interface. Le BFF absorbe ces changements : les services évoluent derrière lui, le contrat avec le front-end reste stable.
La logique d'agrégation dans le navigateur : recoller cinq réponses JSON, gérer les erreurs partielles, réessayer un appel qui a échoué — c'est du code que le navigateur exécute sur le terminal de l'utilisateur, avec sa batterie et sa connexion. Le déplacer côté serveur le rend plus rapide et plus prévisible.
BFF, API Gateway, GraphQL : ne pas confondre
C'est la confusion la plus fréquente. Les trois touchent à la communication entre clients et services, mais ils ne jouent pas le même rôle.
L'API Gateway est un point d'entrée unique pour tous les clients. Elle centralise l'authentification, le rate limiting, le routage. Son défaut : si l'app mobile veut des réponses allégées et le web des réponses complètes, la gateway devient un compromis bancal, un « objet-Dieu » que tout le monde doit se partager.
Le BFF fait l'inverse : il est dédié à un client. Il n'essaie pas de plaire à tout le monde, il sert un front-end précis et l'optimise à fond. On peut d'ailleurs combiner les deux : une gateway en frontal pour les préoccupations transverses, puis un BFF par type de client derrière.
GraphQL attaque le même problème par un autre bout : c'est le client qui décide des données qu'il veut, via une requête. Il résout l'over-fetching sans qu'on écrive un endpoint par écran, mais il apporte sa propre complexité (protection contre les requêtes trop profondes, cache plus difficile qu'en REST). Un BFF peut d'ailleurs exposer du GraphQL en interne.
En pratique : gateway si tous vos clients veulent la même chose, BFF si leurs besoins divergent, GraphQL si votre modèle de données est très interconnecté et que vous voulez donner de l'autonomie au front-end.
Le BFF protège vos jetons d'accès
C'est l'angle qu'on oublie souvent. Une application monopage (React, Vue) qui parle directement à des API doit stocker ses jetons d'accès quelque part dans le navigateur. Or tout ce que le JavaScript du navigateur peut lire, une attaque XSS peut le voler aussi.
Le BFF casse ce schéma. Le jeton ne quitte jamais le serveur : le front-end s'authentifie auprès du BFF, qui pose un cookie de session httpOnly — un cookie que le JavaScript ne peut pas lire. À chaque requête, le BFF récupère le jeton côté serveur et l'injecte dans l'appel vers l'API. Le navigateur ne voit jamais le jeton d'accès. C'est le fondement du BFF pattern recommandé aujourd'hui pour les SPA qui consomment des flux OAuth : les jetons restent côté serveur, dans un cookie signé et chiffré, hors de portée d'un script malveillant.
Une nuance, tout de même : httpOnly empêche de lire le jeton, pas d'en abuser. Une XSS peut toujours déclencher des requêtes au nom de l'utilisateur — le navigateur attache le cookie automatiquement. Le BFF supprime le vol du jeton, pas la faille XSS elle-même : il faut toujours assainir les entrées et se protéger du CSRF.
Next.js baisse fortement le coût d'entrée
Si vous travaillez avec Next.js, vous avez déjà l'outillage sous la main. Les Route Handlers (le dossier app/api/) et les Server Components tournent côté serveur, dans le même projet que votre front-end. Écrire un BFF ne demande pas de déployer un service séparé : c'est une route dans votre application.
import { cookies } from "next/headers";
export async function GET() {
const token = (await cookies()).get("session")?.value;
// Le BFF appelle plusieurs services et assemble la réponse
const [profil, projets, factures] = await Promise.all([
fetch(`${process.env.API}/me`, { headers: { Authorization: `Bearer ${token}` } }),
fetch(`${process.env.API}/projects`, { headers: { Authorization: `Bearer ${token}` } }),
fetch(`${process.env.API}/invoices`, { headers: { Authorization: `Bearer ${token}` } }),
]);
return Response.json({
profil: await profil.json(),
projets: await projets.json(),
// on ne renvoie que ce dont le dashboard a besoin
factures: (await factures.json()).slice(0, 5),
});
}Le front-end fait un seul fetch("/api/dashboard"), le jeton reste dans le cookie httpOnly, et la logique d'agrégation vit côté serveur. C'est un BFF, sans nouvelle brique d'infrastructure. C'est aussi pour ça que la frontière entre « front » et « back » s'est brouillée : côté back de ce type de service, un framework comme FastAPI ou vos microservices existants continuent d'exposer la logique métier, pendant que le BFF se contente de traduire.
Une précision de sécurité sur l'exemple : pour être vraiment carré, le cookie ne devrait pas transporter le jeton d'accès brut comme ici. L'approche la plus propre est un cookie de session opaque — un simple identifiant — le jeton réel restant stocké côté serveur (en session ou dans un cache type Redis). À défaut, un cookie chiffré et signé avec soin.
Et méfiez-vous du raccourci « presque gratuit ». Le code est simple à écrire, pas à exploiter. En production, ce sont les timeouts, les retries, les logs, le monitoring, le cache, les erreurs partielles, la sécurité des cookies et les limites du serverless (durée d'exécution, cold starts) qui font le vrai travail. Next.js baisse le coût d'entrée ; il ne supprime pas le coût d'exploitation.
Ce que le BFF vous apporte
Le gain le plus visible, c'est la vitesse ressentie. Chaque client reçoit ses données déjà mises en forme, donc moins d'appels et moins d'octets transférés, donc une interface qui s'affiche plus vite. Vient ensuite le découplage des équipes : l'équipe front qui possède son BFF le fait évoluer sans attendre l'équipe back-end, et chaque BFF reste assez petit pour tenir dans une tête, là où un back-end partagé grossit sans fin. S'ajoute une isolation des pannes utile au quotidien, un problème sur le BFF mobile ne touchant pas le web, avec la possibilité de couper ou redéployer l'un sans l'autre. Et pour finir, la sécurité : secrets et jetons restent côté serveur, jamais exposés au navigateur.
Les pièges à éviter
Le BFF n'est pas gratuit, et mal utilisé il se retourne contre vous.
Ne mettez pas de logique métier dedans : c'est l'anti-pattern numéro un, même si la frontière mérite d'être précisée. Un BFF contient légitimement de la logique de présentation et d'orchestration — agréger, reformater, filtrer, choisir quels services appeler. Ce qu'il faut lui interdire, ce sont les règles métier durables, les écritures directes en base et les décisions qui relèvent du domaine. Dès qu'il franchit cette ligne, vous recréez le monolithe que vous vouliez éviter. Ces règles-là restent dans les services back-end.
La duplication de code : deux BFF finissent souvent par partager des transformations proches. Vouloir tout factoriser dans un service commun vous ramène vers l'objet-Dieu de la gateway. Un peu de duplication est le prix de l'autonomie des équipes, pas un défaut à corriger à tout prix.
Le saut réseau supplémentaire : le BFF ajoute un intermédiaire, donc une latence. Bien optimisé (appels en parallèle, cache), l'effet est négligeable et largement compensé par la réduction du nombre d'appels côté client. Mal fait, il devient un goulot.
La multiplication des couches : un BFF par client, ça fait des services à déployer, monitorer, sécuriser et versionner. Sur une petite équipe avec un seul front-end, ce coût dépasse souvent le bénéfice.
Quand l'adopter, quand s'en passer
Le BFF prend tout son sens quand vous avez plusieurs clients aux besoins réellement différents : un dashboard web dense, une app mobile épurée, une borne, un portail extranet pour vos clients. Il brille aussi dès que la sécurité des jetons devient critique, ou que vos équipes front et back veulent avancer à des rythmes différents.
À l'inverse, si vous construisez une application avec un seul front-end qui consomme des données dans le même format que le back-end les produit, une API unique reste plus simple et moins chère à maintenir. Ajouter un BFF « au cas où » revient à payer une complexité dont vous n'avez pas encore besoin. Comme souvent en architecture, la bonne question n'est pas « est-ce un beau pattern » mais « quel problème concret est-ce que je résous aujourd'hui ». Sur un produit comme un SaaS multi-plateforme, la réponse penche vite vers le BFF ; sur un logiciel métier mono-interface, rarement.
En pratique, cinq questions suffisent à trancher :
- Plusieurs clients aux besoins vraiment différents ?
- Trop d'appels d'API à orchestrer côté front ?
- Des jetons d'accès exposés au navigateur ?
- Des équipes front et back qui avancent à des rythmes différents ?
- Des coûts d'exploitation (déploiement, monitoring, sécurité) acceptables ?
Plusieurs « oui » et le BFF est probablement rentable. Surtout des « non » : gardez une API unique.
En résumé
Le Backend For Frontend déplace le travail d'agrégation et de mise en forme du navigateur vers un service serveur dédié à chaque client. Il rend les interfaces plus rapides, les jetons plus sûrs et les équipes plus autonomes — à condition de le garder mince, sans logique métier, et de ne le sortir que quand plusieurs clients aux besoins divergents le justifient. Pour une seule interface, une bonne API suffit. Dès que les fronts se multiplient, le BFF devient l'un des patterns les plus rentables pour éviter que votre architecture ne se transforme en plat de spaghettis.




