Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

Backend for Frontend no Node.js

Atualizado em: 26 de agosto de 2026

Estação de trabalho usada no desenvolvimento de aplicações Node.js

O Backend for Frontend no Node.js, conhecido como BFF, cria uma API específica para cada tipo de cliente. Web, aplicativo móvel, painel administrativo e integrações de parceiros podem ter necessidades diferentes de dados, latência, autenticação e formato de resposta.

Em vez de obrigar todos os clientes a consumir uma API genérica e fazer dezenas de chamadas, o BFF agrega serviços internos e entrega um contrato alinhado à interface. Porém, ele não deve copiar regras de negócio nem se tornar um monólito com toda a lógica do sistema.

Neste guia, você aprenderá arquitetura, agregação, contratos, autenticação, cache, falha parcial, timeouts, GraphQL, segurança, observabilidade, deploy e testes.

O que é Backend for Frontend?

Backend for Frontend é um padrão em que cada experiência possui uma camada backend dedicada. A referência Backend for Frontend de Sam Newman apresenta o padrão. A documentação Backends for Frontends Pattern da Microsoft explica cenários e consequências.

Para entrada compartilhada, consulte API Gateway no Node.js. Para contratos, veja OpenAPI com Node.js.

Problema de uma API genérica

Uma tela mobile pode precisar de cinco campos e imagens pequenas. Um painel web pode precisar de tabelas, filtros e detalhes. Uma API única tende a:

  • retornar dados demais;
  • exigir muitas chamadas;
  • acoplar clientes entre si;
  • introduzir parâmetros específicos;
  • ficar difícil de evoluir;
  • transferir composição para o frontend.

Arquitetura

Web App → Web BFF ─┐
Mobile  → Mobile BFF ├→ Serviços internos
Admin   → Admin BFF ─┘

Um API Gateway pode rotear cada cliente ao BFF correto.

BFF versus API Gateway

  • Gateway: autenticação geral, roteamento, limites e proteção.
  • BFF: composição e contrato específico da experiência.

Em sistemas pequenos, um serviço pode cumprir ambos os papéis, mas as responsabilidades devem continuar claras.

Rota agregada

GET /mobile/home

O BFF pode consultar perfil, pedidos recentes e recomendações.

Agregação paralela

const [profile, orders, recommendations] = await Promise.allSettled([
  profileClient.getSummary(userId),
  ordersClient.getRecent(userId, 5),
  recommendationClient.getForUser(userId)
]);

Defina quais respostas são obrigatórias.

Falha parcial

{
  "profile": { "name": "Ana" },
  "recentOrders": [],
  "recommendations": null,
  "warnings": ["recommendations_unavailable"]
}

Uma falha opcional não precisa derrubar a tela inteira.

Dados obrigatórios

Se autenticação ou perfil básico falha, talvez a resposta inteira deva falhar. Classifique dependências.

Timeout por chamada

async function withTimeout(promiseFactory, ms) {
  const controller = new AbortController();
  const timer = setTimeout(() => controller.abort(), ms);

  try {
    return await promiseFactory(controller.signal);
  } finally {
    clearTimeout(timer);
  }
}

Orçamento total

Se a rota possui prazo de 800 ms, cada dependência precisa de orçamento menor. Não espere três serviços por 800 ms em sequência.

Cancelamento

Quando o cliente desconecta, aborte chamadas internas quando possível.

Retries

Repita apenas chamadas idempotentes e dentro do orçamento. Um retry longo pode tornar a tela mais lenta que uma degradação.

Consulte Retry com Backoff no Node.js.

Circuit breaker

Se recomendações falham repetidamente, abra o circuito e retorne sem essa seção.

Bulkhead

Use limites separados por dependência. Um serviço lento não deve consumir todas as conexões do BFF.

Contrato específico

{
  "header": {
    "displayName": "Ana",
    "avatarUrl": "..."
  },
  "cards": [],
  "actions": []
}

O BFF pode devolver um view model próximo ao que a interface precisa.

Não devolva HTML sem necessidade

Um BFF costuma retornar JSON. Server-side rendering é outra decisão e pode coexistir.

Transformação de campos

Converta modelos internos para DTOs externos. Não exponha respostas brutas de microserviços.

Acoplamento ao frontend

O BFF pode evoluir junto com a interface. Isso é uma vantagem, mas exige ownership claro entre equipes.

Versionamento

Clientes móveis antigos permanecem instalados por meses. O Mobile BFF precisa manter contratos compatíveis ou versionados.

Veja Versionamento de API no Node.js.

Web BFF

A web pode ser atualizada rapidamente, permitindo mudanças coordenadas no contrato.

Mobile BFF

Considere:

  • rede lenta;
  • modo offline;
  • payload pequeno;
  • versões antigas;
  • imagens adaptadas;
  • paginação;
  • sincronização incremental.

Admin BFF

Painéis internos podem exigir filtros, auditoria e ações privilegiadas. Não reduza controles de segurança por serem internos.

Parceiros

Um Partner BFF pode adaptar contratos públicos sem expor serviços internos.

GraphQL como BFF

GraphQL permite que o cliente selecione campos, mas ainda precisa de resolvers, autorização, limites e DataLoader.

REST como BFF

REST com endpoints orientados a telas é simples e previsível. Não é necessário adotar GraphQL apenas para ter BFF.

Server-driven UI

O BFF pode retornar blocos e ações para a interface. Isso acelera experimentos, mas aumenta acoplamento e exige schema rigoroso.

Feature flags

O BFF pode avaliar flags por cliente e retornar a variante.

Consulte Feature Flags no Node.js.

Autenticação

O BFF valida sessão ou token e propaga identidade segura aos serviços.

Cookies no Web BFF

Um BFF no mesmo domínio pode usar cookies HttpOnly, Secure e SameSite, reduzindo exposição do token ao JavaScript.

CSRF

Autenticação por cookie exige proteção CSRF em operações de mudança.

Mobile tokens

Aplicativos usam OAuth, PKCE e armazenamento seguro. Consulte OAuth 2.0 com PKCE.

Autorização

O BFF pode ocultar botões, mas os serviços precisam validar permissões. Interface não é barreira de segurança.

Propagação de identidade

Use token interno com audience específica ou headers assinados. Não encaminhe claims arbitrários do cliente.

Token exchange

Em arquiteturas avançadas, o BFF troca o token externo por credencial de serviço limitada.

Segredos

O BFF pode proteger credenciais de APIs de terceiros que não devem chegar ao navegador.

CORS

Quando web e BFF compartilham origem, CORS pode ser evitado. Em origens diferentes, use allowlist.

Cache

Dados públicos podem ser cacheados. Dados por usuário exigem chave correta, private ou no-store.

Cache por seção

Recomendações podem ter TTL de minutos, enquanto saldo precisa de dados atuais.

ETag

Uma resposta agregada pode usar ETag, mas qualquer dependência relevante precisa invalidar a representação.

Paginação

Não agregue coleções infinitas. Use cursor e limites. Consulte Paginação em APIs Node.js.

N+1 interno

Evite consultar um serviço por item. Solicite endpoints batch ou use modelos de leitura.

Batch endpoint

POST /internal/products/batch
{
  "ids": ["1", "2", "3"]
}

O serviço deve limitar quantidade e preservar autorização.

Modelo de leitura

Quando uma tela exige joins constantes entre serviços, uma projeção CQRS pode ser melhor que fan-out em toda requisição.

Veja CQRS no Node.js.

Uploads

O BFF pode emitir URL pré-assinada para object storage, evitando proxy de arquivo grande.

Streaming

Se precisa encaminhar download, use streams e backpressure.

WebSocket

Um BFF pode adaptar eventos internos para o protocolo da interface. Configure autenticação, reconexão e limites.

SSE

Para notificações unidirecionais, SSE pode ser mais simples. Preserve Last-Event-ID.

Erros

Mapeie erros internos para códigos estáveis:

{
  "code": "HOME_PARTIALLY_UNAVAILABLE",
  "message": "Parte do conteúdo não está disponível",
  "requestId": "..."
}

Não exponha topologia

Evite mensagens como “recommendation-service-3 falhou”. Use logs internos para detalhes.

Observabilidade

Registre cliente, versão do app, rota, dependências chamadas, duração e degradações.

Métricas

Monitore:

  • latência total;
  • latência por dependência;
  • falhas parciais;
  • fan-out;
  • payload;
  • cache hit;
  • versões de cliente;
  • timeouts;
  • circuit breaker.

Veja Métricas Prometheus no Node.js.

Tracing

Crie span para a requisição e cada chamada interna. Isso mostra qual serviço domina a latência.

Logs

Use logs estruturados, sem tokens ou respostas completas. Consulte Logs com Pino no Node.js.

Health checks

Liveness verifica o processo. Readiness pode confirmar configuração e conectividade essencial, sem testar todos os serviços a cada segundo.

Graceful shutdown

Pare de receber tráfego, cancele chamadas e aguarde requisições em andamento.

Escalabilidade

Mantenha o BFF stateless. Escale separadamente conforme o tráfego do cliente.

Ownership

A equipe responsável pela experiência deve participar do contrato e das prioridades do BFF.

Duplicação entre BFFs

Alguma duplicação é aceitável para independência. Extraia biblioteca apenas quando a regra é realmente transversal e estável.

Não compartilhe banco de domínio

O BFF deve usar APIs ou modelos de leitura publicados, não consultar tabelas internas de todos os serviços.

Deploy independente

Web e Mobile BFFs podem ter ciclos diferentes. Use contratos internos compatíveis.

Canary

Libere nova composição para uma fração de usuários e compare métricas.

Testes unitários

Teste transformação de DTO, degradação e políticas de timeout.

Testes de contrato

Valide que o BFF continua entendendo respostas dos serviços.

Testes de integração

Simule serviços lentos, indisponíveis e respostas incompletas.

Teste de falha parcial

test('retorna home sem recomendações', async () => {
  recommendations.fail();

  const response = await request('/mobile/home');

  assert.equal(response.status, 200);
  assert.equal(response.body.recommendations, null);
  assert.ok(response.body.warnings.includes(
    'recommendations_unavailable'
  ));
});

Teste de segurança

Confirme que tenant e usuário vêm da identidade validada e que headers forjados são ignorados.

Teste de carga

Meça fan-out, pool de conexões e latência p99 durante falha de dependência.

Quando usar?

  • clientes têm necessidades diferentes;
  • mobile precisa de payload otimizado;
  • web exige composição frequente;
  • equipes evoluem independentemente;
  • segredos devem ficar no servidor;
  • contratos genéricos ficaram complexos.

Quando evitar?

  • um único cliente simples;
  • API já atende bem;
  • equipe não consegue operar mais serviços;
  • o BFF apenas repassa tudo;
  • não existe ownership;
  • duplicação supera o benefício.

Erros comuns

  • Regra de negócio no BFF: domínio diverge.
  • Fan-out sem limite: latência cresce.
  • Sem timeout: tela fica presa.
  • Token no navegador: superfície aumenta.
  • Cache por usuário incorreto: dados vazam.
  • Mesmo BFF para tudo: o padrão perde propósito.
  • Consultar bancos internos: serviços ficam acoplados.

Boas práticas

  • Crie contrato por experiência.
  • Mantenha regras de domínio nos serviços.
  • Defina timeouts.
  • Trate falha parcial.
  • Limite fan-out.
  • Use batch e projeções.
  • Proteja identidade.
  • Meça por dependência.
  • Tenha ownership claro.
  • Adote apenas quando necessário.

Conclusão

O Backend for Frontend no Node.js adapta APIs às necessidades de web, mobile, administração ou parceiros. Ele reduz chamadas, payloads e complexidade no cliente.

O BFF funciona melhor como camada de experiência, não como novo centro de regras de negócio. Com timeouts, falha parcial, contratos específicos e observabilidade por dependência, ele melhora a interface sem criar um gateway monolítico para todos os clientes.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita