Sua equipe mobile está construindo uma página de produto. A API de uso geral retorna dezenas de campos que o telefone nunca exibe, e avaliações, estoque e lista de desejos precisam de mais uma chamada cada. Toda mudança nesses endpoints espera por uma equipe de API que também atende o site e três parceiros.
Um backend for frontend (BFF) dá a cada experiência de cliente a sua própria API pequena do lado do servidor, de propriedade da equipe que constrói o cliente. Este post cobre a origem do padrão, o que um BFF deve fazer, como ele se compara a um API gateway e ao GraphQL, como mantém tokens OAuth fora do navegador, suas armadilhas e como desenhá-lo.
De onde vem o padrão
O SoundCloud deu nome ao padrão. O texto de Phil Calçado de 2015 descreve aplicativos construídos sobre a API pública, em que uma página de perfil chamava /tracks/1234.json, /tracks/1234/related.json, /users/86762.json e /users/me.json e mesclava os resultados por conta própria. Quando as equipes de cliente passaram a ser donas de seus backends, levaram a mesclagem para lá e o aplicativo passou a pedir GET /user-profile/123.json. O líder técnico da web, Nick Fisher, cunhou o termo. Calçado resume: “O BFF fazia parte da aplicação.”
O artigo Backends For Frontends, de Sam Newman, de novembro de 2015, generalizou o padrão: um backend por experiência de usuário, mantido pela equipe que constrói aquela interface.
Clientes tagarelas e APIs de tamanho único
- Clientes tagarelas. O exemplo de Newman é uma lista de desejos: busca-se a lista e depois nomes, preços e níveis de estoque dos itens. São dois round trips dependentes; a, digamos, 150 ms cada em uma rede móvel, passam 300 ms antes de a renderização começar. Com um BFF, o telefone paga um round trip, e as chamadas dependentes rodam dentro do data center, onde um salto custa no máximo alguns milissegundos.
- Payloads dimensionados para a maior tela. O telefone baixa campos que nunca exibe.
- Um gargalo compartilhado. Cada equipe de cliente enfileira mudanças para um único deployável, muitas vezes de propriedade de outra equipe.
Pelo que um BFF é responsável
| Responsabilidade | No BFF | Fora do BFF |
|---|---|---|
| Agregação | Um endpoint por tela, chamando serviços em paralelo | Joins de que todo cliente precisa; eles pertencem a um serviço |
| Modelagem de respostas | Escolher, renomear e formatar campos | Regras de negócio, como preços |
| Autenticação e sessão | Cookie de sessão, armazenamento e renovação de tokens | Autorização final; os serviços decidem |
| Cache | Respostas agregadas de curta duração | Dados personalizados em um cache indexado apenas pela URL |
| Feature flags | Qual variante este cliente vê | Flags que mudam o comportamento do domínio |
BFF vs API gateway vs GraphQL
| API gateway | BFF | Servidor GraphQL | |
|---|---|---|---|
| Atende | Todos os clientes | Uma experiência de cliente | Qualquer cliente, por meio de um esquema |
| Geralmente de propriedade de | Equipe de plataforma | Equipe do cliente | Uma equipe de graph, ou equipes de domínio via federação |
| Faz | TLS, roteamento, verificação de tokens, limites de taxa | Agregação, modelagem, sessão e tokens | Deixa os clientes escolherem campos; resolvers chamam serviços |
| Muda quando uma tela muda | Não | Sim, na mesma release | Muitas vezes só a query muda |
| Falha típica | Lógica de negócio se infiltra | Duplicação, fan-out lento | Queries caras, chamadas de resolvers N+1, cache HTTP mais difícil |
Uma configuração comum coloca um gateway na borda com os BFFs atrás dele, como no diagrama de arquitetura de API gateway. Um graph compartilhado pode substituir BFFs por cliente, e a orientação de padrões da Microsoft observa que, com resolvers específicos de cada frontend, BFFs separados podem não acrescentar nada. O custo é a fronteira entre equipes: cada equipe de cliente negocia mudanças em um único esquema.
Propriedade e fronteiras entre equipes
O BFF pertence à equipe do cliente: o aplicativo web e seu BFF mudam em um único pull request e saem em uma única release. Newman observa que uma equipe mobile pode até mover lógica para o seu BFF para publicar sem passar pela revisão de uma loja de aplicativos.
Quantos BFFs? Newman cita Stewart Gleadow: uma experiência, um BFF. A REA Group mantinha BFFs separados para iOS e Android; o SoundCloud compartilhava um entre seus aplicativos de ouvinte para iOS e Android, e seus engenheiros disseram a Newman que poderiam reconsiderar. A versão de Pete Hodgson é seguir as fronteiras das equipes. Seu organograma de engenharia deve mostrar exatamente uma equipe responsável por BFF.
Um BFF de parceiro mantém um contrato estável e versionado e o mapeia para os serviços à medida que eles mudam, de modo que o trabalho interno não quebre as integrações dos parceiros. Rotear parceiros direto para APIs de serviço versionadas também funciona.
O BFF como gerenciador de tokens para aplicativos de navegador
Uma single-page app que executa o OAuth por conta própria guarda tokens no navegador, onde qualquer script injetado pode roubá-los. O guia de JWT lista onde um aplicativo de navegador pode guardar tokens e o risco de cada opção. A RFC 10017, OAuth 2.0 for Browser-Based Applications, tornou-se uma Best Current Practice (BCP 212) em agosto de 2026. Ela ordena três arquiteturas em ordem decrescente de segurança:
| Padrão | Onde os tokens ficam | O que o JavaScript injetado pode fazer | Veredito da RFC 10017 |
|---|---|---|---|
| BFF | Somente no servidor | Enviar requisições pelo BFF enquanto a página estiver aberta | Fortemente recomendado para aplicativos corporativos e sensíveis |
| Backend mediador de tokens | Access token no navegador, refresh token no servidor | Roubar access tokens e pedir novos ao backend | Somente quando um BFF completo não é viável |
| Cliente OAuth no navegador | Todos os tokens no navegador | Roubar todos os tokens e executar novos fluxos | Não recomendado para aplicativos corporativos ou sensíveis |
Aqui o BFF é um cliente OAuth confidencial. Ele executa o fluxo authorization code com PKCE, troca o código com suas próprias credenciais, armazena os tokens junto à sessão do usuário e anexa o access token a cada chamada que encaminha. O navegador guarda apenas um cookie; o diagrama do fluxo OAuth 2.0 percorre o fluxo de código.
As principais regras da RFC:
- Cookie:
SecureeHttpOnlysão obrigatórios;SameSite=Strict,Path=/, semDomaine um prefixo de nome como__Host-Http-são recomendados. Chrome e Firefox impõem esse prefixo; o Safari, no momento da escrita (novembro de 2026), aplica apenas a parte__Host-. - CSRF: uma defesa é obrigatória. Um cabeçalho personalizado estático em cada chamada de API força um preflight de CORS em requisições entre origens.
- Proxy: encaminhe apenas para hosts da lista de permissões.
- Estado da sessão: um armazenamento no servidor, que a RFC recomenda apenas em pequena escala, ou tokens criptografados no cookie, dentro dos 4.096 bytes por cookie que a RFC 6265 pede que os navegadores suportem. Deixe a sessão durar tanto quanto o refresh token.
Set-Cookie: __Host-Http-sid=3f9c...; Secure; HttpOnly; SameSite=Strict; Path=/
// Same-origin fetch sends the cookie by default.
await fetch("/bff/orders", {
method: "POST",
headers: { "Content-Type": "application/json", "X-CSRF": "1" },
body: JSON.stringify(order),
});
Um BFF não impede o cross-site scripting: código injetado ainda pode chamar o BFF enquanto a página estiver aberta, então mantenha uma Content Security Policy. Aplicativos nativos seguem a RFC 8252, executando o fluxo de código com PKCE no navegador do sistema, de modo que um BFF mobile normalmente apenas valida um bearer token.
Armadilhas
- Lógica duplicada. Newman prefere alguma duplicação a código compartilhado que acople os BFFs. Quando uma lógica aparece pela terceira vez, extraia-a: uma biblioteca para código técnico, um serviço de domínio para lógica de negócio. O SoundCloud construiu um UserProfileService depois que cerca de cinco BFFs montaram, cada um, perfis de usuário.
- O BFF como monolito. Sinais de alerta: ele é dono de dados de domínio ou regras de negócio, outros BFFs o chamam ou várias equipes fazem commits nele. Um desconto calculado pelo BFF web mas não pelo mobile é um bug que um cliente vai encontrar.
- Latência de fan-out. Se um BFF chama cinco serviços em paralelo, a chance de pelo menos um responder mais devagar que o seu próprio p99 é 1 − 0,99^5 ≈ 4,9%: o p95 do BFF é aproximadamente o p99 dos serviços. The Tail at Scale, de Dean e Barroso, cobre contramedidas.
- Mais um salto. Cada BFF adiciona latência, um deploy e uma escala de plantão, e serviços que limitam a taxa por endereço IP agora enxergam apenas o endereço do BFF.
Timeouts, respostas parciais e circuit breakers
Defina um prazo por tela e divida-o: com 800 ms no BFF, um timeout de 300 ms por chamada deixa espaço para uma nova tentativa. Execute chamadas independentes em paralelo e repasse o prazo.
Depois decida quais dados são obrigatórios. A lista de desejos de Newman precisa da lista, mas pode renderizar sem os níveis de estoque. Retorne o que você tem e marque o que falta:
{
"items": [{ "id": "sku-123", "name": "Trail shoe", "price": "$89.00" }],
"stock": null,
"errors": [{ "section": "stock", "reason": "timeout" }]
}
Dê a cada serviço downstream o seu próprio circuit breaker e pool de conexões, para que um serviço lento falhe rápido em vez de prender todos os workers; o padrão circuit breaker cobre limiares e fallbacks. Tente novamente apenas leituras idempotentes, em uma única camada, e não faça cache de respostas agregadas por mais tempo do que a parte mais recente permite.
O diagrama de arquitetura do BFF
Conteúdo do diagrama
- Shared services (domain teams)
- Identity provider
- Session store
- Web app
- Web BFF
- Mobile app
- Mobile BFF
- Partner system
- Partner BFF
- Catalog service
- Orders service
- Profile service
- session cookie only
- bearer access token
- client credentials token
- parallel calls + token
- parallel, fewer fields
- stable v1 mapping
- tokens by session ID
- 1. log in (redirect)
- 2. code + PKCE → tokens
Como ler:
- Uma linha por experiência de cliente, colorida pela equipe responsável. Cada cliente chama apenas o seu próprio BFF.
- Cada BFF se abre em leque para os serviços compartilhados; sua seta termina na moldura porque ele chama os serviços de que suas telas precisarem.
- Arestas tracejadas valem apenas para o login. O navegador é redirecionado ao provedor de identidade e, em seguida, o BFF web troca o código por tokens, o mesmo passo de um login com OpenID Connect.
- Os tokens ficam no servidor, no armazenamento de sessões, sob um ID de sessão. Um cookie criptografado também funciona, e a RFC 10017 o prefere além de implantações pequenas.
- O bloco Markdown lista as configurações do cookie e um exemplo de orçamento por tela.
Desenhando diagramas de BFF com clareza
- Dê uma linha a cada cliente com o seu BFF, rotulada com a equipe responsável.
- Rotule o que atravessa cada aresta: um cookie de sessão, um bearer token ou credenciais de cliente.
- Mostre onde os tokens ficam, em um armazenamento ou em um cookie criptografado.
- Desenhe o gateway separadamente. Uma caixa para o gateway e os BFFs esconde a propriedade.
- Cuidado com o hub. Uma caixa de BFF conectada a todos os clientes é um backend de uso geral.
- Dispense a lista de endpoints. Uma aresta rotulada por BFF até uma fronteira de serviços basta; um diagrama dos microsserviços por trás dos BFFs cobre o lado dos serviços.
Monte no Archboard
- Entre com Google ou GitHub e crie um diagrama.
- No pacote Modelo C4, adicione um Contêiner para o aplicativo web e outro para o aplicativo móvel e um Sistema externo para o parceiro, um por linha.
- Adicione um Contêiner ao lado de cada cliente para o seu BFF, com uma tecnologia e uma descrição.
- Adicione uma Moldura do pacote Básico chamada Shared services (domain teams), contendo três nós Contêiner: catalog, orders e profile.
- Acima da linha web, adicione um Provedor de identidade do pacote Segurança e um nó Redis do pacote Dados como armazenamento de sessões.
- Conecte cada cliente ao seu BFF e cada BFF à moldura, rotule as arestas, deixe tracejadas as duas arestas de login e colora cada linha por equipe.
- Adicione um bloco Markdown do Básico com as configurações do cookie e o orçamento, e rótulos Texto do Básico para as equipes.
Se seus serviços já estão em um flowchart Mermaid, o conversor de Mermaid dá um primeiro rascunho editável. O exemplo usa 13 nós de diagrama e fica dentro do plano Free.
Perguntas frequentes
O que é o padrão backend for frontend (BFF)? Uma API do lado do servidor construída para uma experiência de cliente, como um aplicativo web, um aplicativo móvel ou uma integração de parceiro, e de propriedade da equipe desse cliente. Ela agrega chamadas de backend e molda as respostas.
Qual é a diferença entre um BFF e um API gateway? Um gateway atende todos os clientes e cuida de roteamento, verificação de tokens e limites de taxa. Um BFF atende um cliente e muda junto com as suas telas. Muitos sistemas colocam um gateway na frente de vários BFFs.
O GraphQL substitui o padrão BFF? Pode, porque os clientes escolhem os campos de que precisam. Ainda assim, alguém precisa ser dono do esquema e dos limites de query, e um servidor GraphQL construído para um só cliente é, ele mesmo, um BFF.
Como funciona a autenticação com um BFF? O BFF é um cliente OAuth confidencial: ele executa o fluxo authorization code com PKCE, mantém os tokens no servidor e dá ao navegador apenas um cookie de sessão HttpOnly.
Quantos BFFs devo ter? Um por experiência de usuário, alinhado às suas equipes. Dois aplicativos com a mesma experiência e a mesma equipe responsável podem compartilhar um.