The Backend for Frontend (BFF) pattern is used when it is necessary to provide different APIs or interfaces for various clients (such as mobile applications, web applications, IoT devices) to optimize their interaction with the backend and hide the internal complexity of microservices. Each type of client gets its own BFF server, which implements a specialized API best suited to the client's needs.
This is convenient when working on large systems — different BFFs allow:
Example architecture in Node.js:
// Express for BFF const express = require('express'); const axios = require('axios'); const app = express(); app.get('/profile', async (req, res) => { // Aggregating data from different services const [user, settings] = await Promise.all([ axios.get('http://user-service/api/user'), axios.get('http://settings-service/api/settings') ]); res.json({ name: user.data.name, theme: settings.data.theme }); }); app.listen(3000);
Key features:
Is BFF just a proxy between clients and microservices?
No. The main difference between BFF and a regular proxy is the presence of business logic and data adaptation. BFF translates and aggregates data, rather than just redirecting requests.
Can one BFF be used for all clients?
No, one of the principles of BFF is to dedicate a BFF for each type of client. Using a single BFF loses the benefits of optimal configuration for different interfaces and device types.
Does BFF increase weak coupling between teams?
It is often answered "yes", but this is not the case: adding BFF often increases coupling, as supporting BFF requires collaboration between frontend and backend teams, which necessitates coordination of changes.