O garçom que conhece a mesa
Numa cozinha que atende salão, delivery e balcão, mandar o mesmo prato empratado do mesmo jeito para os três serve mal todo mundo: o delivery precisa embalado, o balcão precisa rápido, o salão precisa bonito. O BFF é o garçom especializado de cada canal: a cozinha (os serviços de domínio) prepara os ingredientes, e cada garçom monta e entrega do jeito que a sua mesa precisa. Um garçom por canal custa mais gente — mas cada mesa recebe exatamente o que espera, sem a cozinha ter que adivinhar para quem está cozinhando.
Um backend que fala a língua do cliente
O BFF não é uma camada a mais por capricho: ele existe porque a fronteira entre o backend genérico e a tela específica é onde mais aparece atrito. A resposta ideal para a home do app não é a ideal para a home do desktop, e forçar as duas numa API só empobrece ambas.
A responsabilidade do BFF é estreita e clara: agregar (juntar várias chamadas numa só), adaptar (mandar só os campos que a tela usa) e formatar (a estrutura que aquele cliente consome). Ele é fino — a regra de negócio continua nos serviços.
O BFF é uma especialização do API Gateway, e a diferença importa. O gateway é um portão único para todos os clientes, focado em tarefas transversais (auth, rate limit, roteamento); o BFF é um portão por cliente, focado em moldar a resposta àquela interface. Muitos sistemas têm os dois: o gateway na frente cuida do transversal, e atrás dele há um BFF por tipo de cliente cuidando da adaptação. Confundi-los leva a um gateway inchado tentando também formatar respostas — ou a BFFs reimplementando auth que já era do gateway.
A ligação com a Lei de Conway é direta e explica por que o padrão nasceu: um BFF costuma existir porque há um time dono daquele frontend, que quer evoluir seu backend sem depender do time de plataforma. A arquitetura (um backend por cliente) espelha a organização (um time por cliente). O risco a vigiar é a duplicação: se a mesma regra aparece no BFF de web e no de mobile, ou ela é de apresentação (tudo bem, cada tela é diferente) ou é de domínio — e aí ela vazou para a borda e deveria voltar para os serviços, antes que as cópias divirjam.
Como isso aparece na prática
A home mobile que fazia cinco chamadas
Cenário
Para montar a tela inicial, o app fazia cinco requisições a uma API genérica e descartava metade dos campos que vinham. Em redes móveis lentas, a home demorava e consumia bateria e dados à toa.
Como o padrão entra
Um BFF mobile passou a agregar as cinco chamadas numa só e a devolver exatamente os campos daquela tela. O app passou a fazer uma requisição enxuta por tela.
Trade-off: Surgiu um serviço BFF a mais para o time mobile manter e versionar. Em troca, a home ficou rápida, e o app deixou de carregar dados que nunca usava.
A regra de negócio que vazou para os BFFs
Cenário
O cálculo de elegibilidade de um desconto foi implementado no BFF de web e, depois, copiado no BFF de mobile. As duas cópias divergiram, e web e app passaram a mostrar descontos diferentes para o mesmo usuário.
Como o padrão entra
O cálculo foi movido para o serviço de domínio, e os BFFs voltaram a só agregar e formatar. A regra passou a existir num lugar só, consumida por ambos.
Trade-off: Os BFFs ficaram mais 'burros', dependendo de mais um serviço. É exatamente o objetivo: regra de negócio mora no domínio; o BFF só adapta para o cliente.
Onde isto dá errado
Colocar regra de negócio no BFF
O BFF deve agregar e formatar, não decidir. Regra de negócio na borda tende a ser copiada para cada BFF e a divergir entre eles — web e mobile passam a discordar sobre o mesmo fato. Regra mora no domínio.
Criar um BFF sem clientes distintos
Se há um tipo de cliente só, ou todos precisam do mesmo, o BFF é uma camada de rede a mais sem função. O padrão se paga quando as necessidades por cliente são genuinamente diferentes.
Confundir BFF com API Gateway
O gateway é um portão único focado no transversal (auth, rate limit); o BFF é por cliente e focado em moldar a resposta. Fundir os dois gera um gateway inchado formatando respostas — responsabilidades que deveriam ficar separadas.
Agregar e enxugar por cliente
// Sem BFF: uma API generica serve web, iOS e Android. O app mobile
// faz 5 chamadas e recebe campos que nao usa — rede lenta, bateria.
await Promise.all([
fetch("/api/usuario"), fetch("/api/pedidos"),
fetch("/api/enderecos"), fetch("/api/pontos"), fetch("/api/cupons"),
]); // 5 idas ao servidor so para montar UMA tela do celular.
// COM BFF: um backend por tipo de cliente, moldado a ELE.
// bff-mobile agrega e enxuga para a tela do app numa chamada so:
app.get("/mobile/home", async (req, res) => {
const [usuario, pedidos, pontos] = await Promise.all([
servicos.usuario(req.userId),
servicos.pedidos(req.userId),
servicos.fidelidade(req.userId),
]);
res.json({ // resposta sob medida para a home mobile:
nome: usuario.nome, // so os campos que ESTA tela usa
ultimosPedidos: pedidos.slice(0, 3),
pontos: pontos.total,
});
});
// O app faz 1 chamada e recebe exatamente o que a tela precisa.
// O bff-web pode devolver algo diferente para a MESMA home no desktop.Quando usar × quando evitar
Use quando
3- Quando clientes diferentes têm necessidades de dados e formato distintas.
- Para poupar rede e bateria do mobile agregando chamadas.
- Quando cada frontend tem um time que quer evoluir no próprio ritmo.
Evite quando
2- Quando há um único tipo de cliente ou necessidades quase iguais.
- Quando a lógica seria de domínio e deveria viver nos serviços.
Testar o que ficou
3 armadilhas de Backend for Frontend (BFF) viram perguntas, com o nome do padrão escondido, misturadas com padrões parecidos.
Onde isto aparece de verdade
Você já usa isto, talvez sem saber o nome.
um backend por app (web, iOS, Android)Cada cliente ganha um backend feito sob medida para as necessidades dele, em vez de uma API genérica para todos.o BFF do SoundCloud / NetflixAs empresas que popularizaram o padrão, cansadas de uma API única tentando servir web e mobile ao mesmo tempo.agregar chamadas para o mobileUm BFF junta várias chamadas de serviços numa resposta só, poupando a rede lenta e a bateria do celular.
O padrão em uma linha
Sem nome de domínio, sem cerimônia. Só a ideia.
// API moldada para UMA experiência de UI.
const home = await bff.montarHome(userId); // agrega 3 serviçosO que ele cobra
2 saltos a mais entre a chamada e o efeito.
- Mais um serviço por tipo de cliente para desenvolver, versionar e manter em pé
- Lógica pode se duplicar entre os BFFs se algo comum a todos os clientes for parar em cada um
Não vale se: há um único tipo de cliente, ou os clientes têm necessidades quase idênticas — aí um backend só serve a todos sem atrito.
Costuma ser confundido com
Onde isto aparece
Continue por aqui
- API GatewayNum sistema de muitos serviços, um ponto único de entrada por onde tudo passa: o API Gateway roteia cada requisição ao serviço certo e concentra o que é transversal — autenticação, rate limiting, CORS, log — para os serviços não repetirem isso cada um. O cliente conhece só o gateway, e a topologia interna pode mudar por trás. O risco é o gateway virar gargalo, ponto único de falha, ou um monólito de fronteira inchado de regra.
- Lei de ConwaySistemas espelham a estrutura de comunicação de quem os constrói. Dois times que mal se falam produzem uma integração pobre entre seus módulos — não por falha técnica, mas por organograma. A consequência prática é poderosa: para obter a arquitetura que você quer, muitas vezes é preciso primeiro organizar os times na forma dessa arquitetura.
- Arquitetura HexagonalIsola o domínio no centro e o conecta ao mundo externo por portas (interfaces) e adaptadores (implementações), tornando infraestrutura um detalhe plugável.