Compreendendo o padrão Backend for Frontend (BFF): um guia simples
Em uma arquitetura de microsserviços, nossos sistemas são divididos em dezenas de serviços pequenos e focados, como um serviço de usuário, um serviço de pedido e um serviço de produto.
Mas quando se trata de exibir essas informações aos usuários, dispositivos diferentes têm necessidades muito diferentes. Um navegador da web em um computador desktop de alta velocidade deseja um painel rico cheio de tabelas, barras laterais e gráficos. Um aplicativo móvel em uma rede celular lenta deseja um layout simples e leve para economizar largura de banda e bateria. Um aplicativo smartwatch pode precisar apenas de uma única linha de texto.
Se todos esses front-ends consultarem exatamente a mesma API de back-end, alguém terá que se comprometer. Ou o aplicativo móvel é forçado a baixar grandes quantidades de dados inúteis ou o aplicativo web é forçado a fazer dezenas de solicitações de rede separadas para buscar tudo o que precisa.
Este é exatamente o problema resolvido pelo Padrão Backend for Frontend (BFF). Neste guia, explicaremos esse padrão em palavras simples, veremos uma analogia do mundo real, compará-lo-emos com um API Gateway padrão e percorreremos uma implementação prática de código.
A analogia do mundo real: o menu do restaurante
Imagine um restaurante que serve três tipos de clientes bem diferentes:
- Um crítico gastronômico que deseja um menu degustação completo de 5 pratos com listas detalhadas de ingredientes.
- Um viajante ocupado que quer um lanche rápido e pré-embalado para comer no trem.
- Uma criança que quer uma refeição infantil simples, com porções pequenas e sem ingredientes picantes.
Se o restaurante tivesse apenas um único menu que listasse todas as três opções detalhadamente, seria opressor. O viajante perderia tempo lendo receitas de 5 pratos, e os pais da criança teriam dificuldade para encontrar opções simples de comida.
Em vez disso, o restaurante imprime três menus personalizados: um menu de degustação, um menu expresso para viagem e um menu infantil.
Cada cardápio vem da mesma cozinha (os microsserviços), mas formata e dimensiona as opções especificamente para aquele cliente (o cliente).
Neste cenário:
- A cozinha representa seus microsserviços (Usuário, Catálogo, Pagamento).
- Os menus personalizados são seus BFFs (Web BFF, Mobile BFF, Watch BFF).
- Os clientes são seus frontends (navegador de desktop, aplicativo móvel, smartwatch).
O problema: a API “tamanho único”
Quando os microsserviços se tornaram populares, muitas equipes criaram um API Gateway único e compartilhado para lidar com todos os clientes front-end:
Embora um único ponto de entrada seja ótimo, uma API compartilhada apresenta vários gargalos de escalabilidade:
- Payload Bloat for Mobile: o aplicativo web para desktop precisa do histórico de pedidos do usuário, endereço de cobrança, foto do perfil e pontos de fidelidade. O aplicativo móvel só precisa mostrar “Último pedido: Enviado”. Com uma API compartilhada, o aplicativo móvel baixa toda a carga útil do perfil, desperdiçando dados preciosos e retardando o tempo de carregamento.
- Gargalos de API: uma única equipe se torna o gargalo do gateway compartilhado. Se a equipe do iOS quiser alterar um pequeno campo de layout, ela deverá esperar que a equipe do gateway compartilhado implante uma nova versão, retardando os ciclos de desenvolvimento.
- Diferentes necessidades de segurança: um navegador da Web pode exigir sessões baseadas em cookies para evitar Cross-Site Scripting (XSS), enquanto um aplicativo móvel prefere cabeçalhos OAuth baseados em token. Lidar com ambos em um único servidor cria códigos complexos e confusos.
A solução: o padrão BFF
Em vez de criar um gateway gigante para todos os dispositivos, o Padrão BFF defende a construção de um servidor back-end dedicado para cada aplicativo front-end.
Você terá:
- Web BFF: Lida com solicitações do navegador do desktop. Ele agrega perfis completos, catálogos de produtos e informações detalhadas de checkout.
- Mobile BFF: lida com solicitações de aplicativos iOS e Android. Ele agrega dados, filtra campos desnecessários e compacta a resposta final para garantir desempenho rápido.
API Gateway vs. BFF: Qual é a diferença?
É comum confundir esses dois padrões porque ambos ficam entre o cliente e os microsserviços. Aqui está a distinção:
| Recurso | Gateway de API geral | Back-end para Front-end (BFF) |
|---|---|---|
| Número de gateways | Normalmente um para todo o sistema. | Vários (um para cada tipo de dispositivo cliente). |
| Responsabilidade | Roteamento de alto nível, limitação de taxa e segurança global. | Agregar dados e adaptar cargas úteis para um front-end específico. |
| Propriedade | Gerenciado por uma equipe dedicada de infraestrutura de back-end/plataforma. | Gerenciado pela equipe de front-end que cria o aplicativo correspondente. |
| Personalização | Baixo. As alterações afetam todos os clientes. | Alto. As alterações afetam apenas um aplicativo cliente. |
Uma implementação prática (Node.js/Express)
Para entender como isso funciona na prática, vamos escrever um exemplo simples de Node.js.
Imagine que temos dois microsserviços rodando internamente:
- Atendimento ao usuário (retorna informações básicas do perfil do usuário)
- Serviço de pedidos (retorna uma lista de pedidos com detalhes completos)
Queremos criar uma melhor amiga da Web e uma melhor amiga móvel para servir nosso site para desktop e aplicativo móvel de maneira diferente.
1. A simulação de microsserviços compartilhados
Primeiro, aqui estão os dados simulados para nossos dois microsserviços subjacentes:
// 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. The Web BFF (devolve carga útil detalhada completa)
O Web BFF agrega todos os campos porque a tela do desktop tem bastante espaço para mostrá-los:
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. O melhor amigo móvel (retornos minimizados, carga útil agregada)
O Mobile BFF filtra campos desnecessários (como e-mail, configurações e impostos) e agrega os itens do pedido para economizar largura de banda:
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'));
Comparação do tamanho da carga útil
- Tamanho da resposta do Web BFF: Contém configuração aninhada, preferências, lista completa de pedidos, impostos, itens, etc. (Aprox. 400 bytes).
- Tamanho da resposta do melhor amigo móvel: contém apenas 6 pares de valores-chave que representam o essencial. (Aproximadamente 120 bytes—redução de 70% no tamanho da rede!).
Prós e contras do padrão BFF
Embora altamente eficaz, o padrão BFF tem vantagens e desvantagens:
| Vantagem (Pró) | Desvantagem (Con) |
|---|---|
| Desempenho otimizado do cliente: os clientes carregam apenas os dados exatos de que precisam, reduzindo o consumo de bateria e uso de memória. | Duplicação de código: você pode acabar escrevendo uma lógica de busca de dados semelhante em várias bases de código BFF. |
| Ciclos de lançamento mais rápidos: a equipe de front-end móvel pode atualizar seu servidor BFF sem precisar coordenar com desenvolvedores web. | Maior contagem de servidores: em vez de gerenciar um gateway de API, agora você precisa implantar e gerenciar vários serviços BFF. |
| Código de front-end simplificado: o cliente não precisa lidar com lógica complexa de classificação, filtragem ou mesclagem; apenas exibe o JSON que recebe. | Gerenciamento de segurança: certificações SSL/TLS, regras de limite de taxa e firewalls devem ser gerenciados em vários gateways. |
Conclusão
O padrão Backend for Frontend (BFF) é uma arquitetura poderosa para sistemas que atendem a vários tipos de clientes, como dispositivos web, móveis e IoT. Ao criar gateways personalizados para cada front-end específico, você separa o desenvolvimento do cliente, minimiza o tamanho da carga útil e oferece uma experiência de usuário mais rápida e responsiva.
Se o seu sistema tiver apenas um aplicativo da web, um API Gateway compartilhado será suficiente. Mas no momento em que você começa a criar aplicativos móveis ou experiências de dispositivos especializados junto com seu aplicativo web, implementar um BFF é a melhor maneira de manter suas arquiteturas de front-end e back-end limpas, otimizadas e independentes.
Explore mais insights sobre desenvolvimento de software e engenharia de back-end no Blog Ghaznix →