
Você já tentou usar a mesma API REST para servir um app mobile 3G, um dashboard admin rico e um smartwatch com tela de 1 polegada? Se sim, você sabe o problema: um tamanho não serve para todos.
O padrão Backend For Frontend (BFF) resolve isso criando backends especializados e otimizados para cada tipo de cliente.
A abordagem tradicional é criar um único backend REST que tenta agradar todos os clientes:
[Mobile App] ────┐
[Web Dashboard] ──┤──► Generic API ──► Microservices
[Smart Watch] ───┘
A API retorna 50 campos, mas o mobile só usa 5. Você desperdiçou dados móveis e bateria do usuário.
// API genérica retorna tudo
{
"user": {
"id": 123,
"name": "Anderson",
"email": "...",
"address": { /* 10 campos */ },
"preferences": { /* 20 campos */ },
"admin_metadata": { /* dados que o mobile nunca usa */ }
}
}
O dashboard precisa de dados de 5 endpoints diferentes. O cliente faz 5 chamadas HTTP sequenciais. Latência explode.
O cliente tem que transformar os dados brutos em formatos específicos para sua UI. Isso vaza lógica de negócio para o frontend.
Crie backends dedicados para cada plataforma:
[Mobile App] ──► Mobile BFF ──┐
[Web Dashboard] ──► Web BFF ──┤──► Microservices
[Admin Panel] ──► Admin BFF ──┘
Cada BFF:
// mobile-bff/routes/product.js
app.get('/product/:id', async (req, res) => {
const product = await productService.get(req.params.id);
const reviews = await reviewService.getSummary(req.params.id); // Só média e contagem
res.json({
id: product.id,
name: product.name,
price: product.price,
image: product.thumbnailUrl, // Versão comprimida
rating: reviews.average
});
});
// web-bff/routes/product.js
app.get('/product/:id', async (req, res) => {
const product = await productService.get(req.params.id);
const reviews = await reviewService.getFull(req.params.id); // Todas as reviews
const recommendations = await mlService.getRecommendations(req.params.id);
const inventory = await inventoryService.getStock(req.params.id);
res.json({
...product, // Todos os campos
reviews: reviews.items,
relatedProducts: recommendations,
stockByWarehouse: inventory
});
});
// admin-bff/routes/product.js
app.get('/product/:id', async (req, res) => {
const product = await productService.get(req.params.id);
const analytics = await analyticsService.getProductMetrics(req.params.id);
res.json({
...product,
metrics: {
views: analytics.totalViews,
conversionRate: analytics.conversionRate,
revenue: analytics.totalRevenue
}
});
});
Você pode mudar o BFF do mobile sem quebrar o dashboard web. Deploys desacoplados.
O Admin BFF valida tokens de admin. O Mobile BFF valida OAuth de redes sociais. Lógica separada, mais segura.
BFF é majoritariamente "cola" (aggregation). Node.js com async/await é ideal.
// mobile-bff/server.js
import express from 'express';
const app = express();
app.get('/home', async (req, res) => {
const [banners, products, user] = await Promise.all([
fetch('http://content-svc/banners'),
fetch('http://product-svc/featured'),
fetch('http://user-svc/me', { headers: req.headers })
]);
res.json({ banners, products, user });
});
Em vez de múltiplos BFFs REST, use um GraphQL Gateway e deixe o cliente pedir apenas os campos que precisa.
Trade-off: GraphQL tem overhead de aprendizado. BFF REST é mais simples.
Se o frontend é Next.js, as rotas /api/* funcionam como BFF embutido.
// pages/api/product/[id].js
export default async function handler(req, res) {
const product = await fetch(`http://product-svc/${req.query.id}`);
res.json(product);
}
Se todos os BFFs fazem autenticação igual, você repetiu código. Solução: Crie bibliotecas compartilhadas (npm packages privados).
Se você coloca lógica de negócio no BFF (ex: cálculo de desconto), você criou um novo monolito. BFF é orquestração, não negócio.
Não crie um BFF para cada tela. Crie um BFF por plataforma/contexto (Mobile, Web, Admin), não por feature.
Diferença sutil mas importante:
Você pode (e deve) ter ambos: API Gateway na frente, BFFs atrás.
Client ──► API Gateway ──► BFF ──► Microservices
BFF não é um padrão novo. Ele é a formalização de algo que bons engenheiros sempre fizeram: customizar backends para necessidades específicas de clientes.
A pergunta não é "devo usar BFF?". A pergunta é: "quantos frontends diferentes eu tenho e quantos backends genéricos estou forçando neles?"
Produtos gratuitos e pagos para transformar ideias em uma base que você consegue executar.
13 produtos disponíveisContinue explorando tópicos similares

Designing APIs that match what clients actually need, not your internal architecture.

Em arquiteturas de microservices, o API Gateway é o ponto de entrada único que resolve cross-cutting concerns. Descubra padrões e armadilhas.

Especificar a API antes de codificar não é burocracia, é engenharia. Descubra como o API Design First elimina retrabalho e melhora DevEx.
Checklist de 47 pontos para encontrar bugs, riscos de segurança e problemas de performance antes do lançamento.
Templates testados em produção, usados por desenvolvedores. Economize semanas de setup no seu próximo projeto.