Versículo chave: "Consagre ao Senhor tudo o que você faz, e os seus planos serão bem-sucedidos." - Provérbios 16:3
Conforme aumenta a complexidade dos produtos que desenvolvemos, mais provável é que aumente também a quantidade de “caras” que ele vai ter. Hoje é muito comum, por exemplo, um mesmo produto ter uma interface web, outra móvel e outra responsiva. Neste contexto, entendo que seja bastante tentador projetar uma única API de back-end para todas as interfaces, que seja reutilizável.
Entretanto, é claro que, como sempre, em um produto complexo uma solução simples não cai bem. As necessidades e restrições são bastante variáveis, e às vezes é necessária uma personalização. Para resolver este problema, é que entra em cena o BFF, que até pode ser considerado um best friends forever, mas significa na verdade Back-end for Front-end.
A Arquitetura BFF - Backend for Frontend é um padrão onde você cria um back-end específico para cada tipo de front-end (como web, mobile ou desktop). Em vez de ter um único back-end genérico que serve para todos, cada front-end tem seu próprio "mini-backend" adaptado às suas necessidades, reduzindo a complexidade no cliente e otimizando a performance.
Por exemplo, uma API BFF para um app mobile pode retornar dados já filtrados e otimizados para economia de banda, enquanto o BFF da versão web pode fornecer dados mais completos. Essa abordagem melhora a experiência do usuário, facilita manutenção e testes, e evita lógica excessiva no front-end.
A arquitetura BFF se encaixa muito bem com microserviços. Na verdade, ela é frequentemente usada em conjunto com microserviços para resolver um problema comum: a complexidade de consumir diretamente múltiplos serviços no front-end.
Warning
Aviso: Os detalhes deste post foram extraídos do Blog de Engenharia do SoundCloud. Todo o crédito pelos detalhes técnicos pertence à equipe de engenharia do SoundCloud. Os links para os artigos originais estão presentes na seção de referências no final do post. Tentamos analisar os detalhes e fornecer nossa opinião sobre eles. Se você encontrar alguma imprecisão ou omissão, deixe um comentário e faremos o possível para corrigi-las.
Assim como na vida real, os melhores amigos também podem ser salvadores quando se trata de projetos de software.
O SoundCloud descobriu isso quando quis evoluir sua arquitetura de serviço para lidar com milhões de solicitações por hora.
Caso você não saiba, o SoundCloud é um site online para ouvir música gratuitamente. Eles têm mais de 320 milhões de faixas musicais e a maior comunidade online do mundo de artistas, bandas, DJs e criadores de áudio.
Inicialmente, o aplicativo web do SoundCloud seguia o que eles chamavam de abordagem "comer a própria ração". Uma única API monolítica atendia aos requisitos de aplicativos oficiais e integrações de terceiros.
Naturalmente, com o crescimento do SoundCloud, essa abordagem tornou-se insuficiente para suas necessidades de escalabilidade operacional e organizacional, resultando em uma migração da arquitetura monolítica para microsserviços.
No entanto, isso se mostrou mais fácil na teoria do que na prática. Com a criação de novos microsserviços, os clientes que dependiam do monolito passaram a ter que acessar múltiplos serviços para obter os dados necessários. Isso dificultou o desenvolvimento para os clientes, incluindo aplicativos de terceiros que utilizavam o SoundCloud.
Como essa situação era insustentável, o SoundCloud precisou criar uma maneira de facilitar o desenvolvimento para os aplicativos clientes, mantendo a arquitetura de microsserviços subjacente. Neste artigo, veremos como eles alcançaram esses objetivos com BFFs (Browser Forwarders), Serviços de Valor Agregado e Gateways de Domínio.
BFFs no SoundCloud: O termo BFF significa Backends-for-Frontends (Backends para Frontends). Em termos mais simples, pense em um BFF como um gateway de API dedicado para cada dispositivo ou tipo de interface que interage com seu aplicativo.
O diagrama abaixo mostra uma visão geral do BFF:
Em um sistema de microserviços, cada serviço é especializado em uma funcionalidade (como autenticação, pagamentos, produtos etc.), mas o front-end precisaria orquestrar várias chamadas, lidar com autenticação, formatação, e mais. O BFF entra nesse ponto como uma camada de orquestração entre os microserviços e o front-end.
Ele agrega, adapta e transforma os dados de vários serviços para entregar ao front-end exatamente o que ele precisa, sem que o front precise entender toda a estrutura dos serviços internos. Isso melhora a performance, simplifica o front-end e ajuda a manter separação de responsabilidades.
Discutimos o API Gateway. Essa abordagem é boa se tivermos um único cliente na web ou no celular. Se nosso aplicativo for usado por vários clientes, como web, dispositivos móveis, IoT, etc., não é uma boa ideia usar um único API Gateway para todos os tipos de clientes. O processo ficará complicado rapidamente e poderá inchar o serviço API Gateway, tornando-o um único serviço Monolith.
![]() |
![]() |
A melhor abordagem para esse tipo de cenário é usar um API Gateway separado para cada tipo de cliente, esse padrão de arquitetura é chamado de padrão Backend for FrontEnd (BFF) e se tornou uma palavra da moda.
A equipe de engenharia do SoundCloud opera dezenas de BFFs (Broadcast Frameworks), cada um atendendo a um tipo específico de cliente. Por exemplo, um BFF chamado API Móvel atende clientes Android e iOS. Há também um BFF de API Web que lida com a interface web e os widgets. Além disso, existem BFFs dedicados para APIs públicas e de parceiros.
Todo o tráfego externo que chega ao SoundCloud passa por um dos BFFs. Esses BFFs também lidam com diversas funcionalidades, como:
- Limitação de taxa
- Autenticação
- Sanitização de cabeçalho
- Controle de cache
O padrão BFF é um paradigma arquitetônico, uma variante do padrão de API Gateway e compreende vários back-ends projetados para atender às demandas de aplicativos front-end específicos, como desktop, navegador e aplicativos móveis nativos, dispositivos IoT etc.
Para facilitar o compartilhamento de lógica comum entre todos os BFFs (Broadcast Frameworks for Frontiers), todos eles utilizam uma biblioteca interna que fornece recursos avançados. Quaisquer alterações nessa biblioteca são implementadas automaticamente em questão de horas.
O SoundCloud segue a filosofia de desenvolvimento de código-fonte interno para esses BFFs.
De acordo com essa filosofia, equipes individuais podem contribuir para a base de código do BFF, e uma equipe central revisa cada alteração com base nos princípios discutidos no Coletivo. Esse Coletivo, organizado por um Líder de Plataforma, se reúne regularmente para discutir problemas e compartilhar conhecimento.
Vantagens do BFF: Os BFFs oferecem diversas vantagens. Vejamos algumas das principais.
1 - Autonomia: A autonomia é talvez o maior valor agregado ao usar um BFF.
APIs separadas por tipo de cliente significam que podemos otimizar a API para o que for mais conveniente para um determinado tipo de cliente.
Por exemplo, no caso do SoundCloud, os clientes móveis preferiam respostas maiores com um número maior de entidades incorporadas como forma de minimizar o número de solicitações. Em contraste, o front-end web prefere respostas mais granulares.
Os BFFs atendem a essas demandas variáveis para cada tipo de cliente.
2 - Resiliência e Menor Risco: Os BFFs também reduzem o risco geral de indisponibilidade do aplicativo.
Embora uma implantação malsucedida possa derrubar um BFF inteiro em uma zona de disponibilidade, isso não derruba toda a plataforma, o que era uma possibilidade com a abordagem de API monolítica.
Veja o diagrama abaixo que representa um cenário em que a indisponibilidade do BFF móvel não significa que o BFF web também ficará indisponível.
Sistema completo de gerenciamento de tarefas com arquitetura de microsserviços e padrão Backend For Frontend (BFF), construído com TypeScript/Node.js, Prisma, React.js e React Native.
📐 Arquitetura
┌──────────────┐ ┌──────────────┐
│ Web App │ │ Mobile App │
│ React.js │ │ React Native │
│ + Redux │ │ + Redux │
└──────┬───────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ BFF Web │ │ BFF Mobile │
│ Node :3001 │ │ Node :3002 │
└──────┬───────┘ └──────┬───────┘
│ │
└──────────┬──────────┘
│ (fan-out paralelo)
┌─────────────┼─────────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Auth │ │ User │ │ Task │ │ Notification │
│ :4001 │ │ :4002 │ │ :4003 │ │ :4004 │
└───┬────┘ └────┬─────┘ └──────┬───────┘ └──────┬───────┘
│ │ │ │
▼ ▼ ▼ ▼
auth_db user_db task_db notif_db
(PostgreSQL) (PostgreSQL) (PostgreSQL) (PostgreSQL)
Por que BFF?
O padrão BFF cria um backend dedicado para cada tipo de cliente:
- BFF Web — agrega dados de múltiplos serviços em uma única chamada (ex:
/dashboardretorna usuário + stats + tarefas + notificações em paralelo) - BFF Mobile — retorna payloads menores otimizados para bandwidth limitado (sem campos desnecessários)
🗂️ Estrutura do Projeto
bff-app/
├── docker-compose.yml
├── package.json # Workspace raiz (npm workspaces)
├── shared/
│ └── types.ts # Tipos TypeScript compartilhados
│
├── services/
│ ├── auth-service/ # JWT + refresh token rotativo
│ ├── user-service/ # Perfil de usuário
│ ├── task-service/ # CRUD tarefas + comentários
│ ├── notification-service/ # Notificações push
│ ├── bff-web/ # BFF para React.js
│ └── bff-mobile/ # BFF para React Native
│
├── web/ # React.js + Redux + Tailwind
└── mobile/ # React Native (Expo) + Redux
🛠️ Stack Tecnológica
| Camada | Tecnologia |
|---|---|
| Microsserviços | Node.js + Express + TypeScript |
| ORM | Prisma 5 + PostgreSQL |
| Autenticação | JWT (access 15min) + Refresh Token rotativo |
| Cache/Session | Redis |
| Web App | React 18 + Redux Toolkit + React Query + Vite |
| Estilização Web | Tailwind CSS + React Hook Form + Zod |
| Mobile App | React Native (Expo) + Redux Toolkit |
| Containerização | Docker + Docker Compose |
⚡ Início Rápido
Pré-requisitos
- Docker & Docker Compose
- Node.js 20+
- Subir com Docker (recomendado)
git clone <repo>
cd bff-app
# Subir todos os serviços (BD, Redis, microsserviços)
docker-compose up -d
# Ver logs
docker-compose logs -f bff-web bff-mobile- Desenvolvimento Local
# Instalar dependências de todos os workspaces
npm install
# Subir apenas os bancos de dados e Redis
docker-compose up -d postgres-auth postgres-user postgres-task postgres-notification redis
# Rodar migrações em todos os serviços
npm run db:migrate
# Subir todos os serviços em modo dev
npm run dev- App Web
cd web
npm run dev
# Acesse: http://localhost:3000- App Mobile
cd mobile
npx expo start
# Escaneie o QR code com o app Expo Go🌐 Portas dos Serviços
| Serviço | Porta |
|---|---|
| BFF Web | 3001 |
| BFF Mobile | 3002 |
| Auth Service | 4001 |
| User Service | 4002 |
| Task Service | 4003 |
| Notification Service | 4004 |
| Web App (Vite) | 3000 |
| PostgreSQL Auth | 5432 |
| PostgreSQL User | 5433 |
| PostgreSQL Task | 5434 |
| PostgreSQL Notif. | 5435 |
| Redis | 6379 |
📡 Endpoints BFF Web
Autenticação (público)
| Método | Rota | Descrição |
|---|---|---|
| POST | /api/auth/register |
Criar conta |
| POST | /api/auth/login |
Login |
| POST | /api/auth/refresh |
Renovar access token |
| POST | /api/auth/logout |
Logout |
Autenticado (Bearer token)
| Método | Rota | Descrição |
|---|---|---|
| GET | /api/dashboard |
🔥 Agregado: user + stats + tarefas + notif |
| GET | /api/tasks |
Listar tarefas (filtros + paginação) |
| POST | /api/tasks |
Criar tarefa |
| PATCH | /api/tasks/:id |
Atualizar tarefa |
| DELETE | /api/tasks/:id |
Excluir tarefa |
| GET | /api/tasks/:id/detail |
Tarefa + perfil do assignee |
| GET | /api/notifications |
Listar notificações |
| PATCH | /api/notifications/:id/read |
Marcar como lida |
| PATCH | /api/notifications/read-all |
Marcar todas como lidas |
| GET | /api/profile |
Ver perfil |
| PATCH | /api/profile |
Atualizar perfil |
🔑 Variáveis de Ambiente
Crie um arquivo .env em cada serviço (já configurado no docker-compose):
# auth-service
DATABASE_URL=postgresql://postgres:postgres@localhost:5432/auth_db
JWT_SECRET=mude-em-producao
JWT_REFRESH_SECRET=mude-em-producao
PORT=4001
# bff-web
AUTH_SERVICE_URL=http://localhost:4001
USER_SERVICE_URL=http://localhost:4002
TASK_SERVICE_URL=http://localhost:4003
NOTIFICATION_SERVICE_URL=http://localhost:4004
ALLOWED_ORIGINS=http://localhost:3000
PORT=3001
# mobile (Expo)
EXPO_PUBLIC_API_URL=http://localhost:3002/api🗄️ Modelos de Dados
Auth Service
User— credenciais (email + hash da senha)RefreshToken— tokens rotativos com expiração
User Service
User— perfil (nome, avatar, bio)
Task Service
Task— título, descrição, status, prioridade, assignee, tags, prazoComment— comentários por tarefa
Notification Service
Notification— tipo, título, mensagem, lida/não-lida, metadata
🧪 Testando a API
# Registrar
curl -X POST http://localhost:3001/api/auth/register \
-H "Content-Type: application/json" \
-d '{"name":"João","email":"joao@email.com","password":"senha123"}'
# Login
curl -X POST http://localhost:3001/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"joao@email.com","password":"senha123"}'
# Dashboard (substitua TOKEN)
curl http://localhost:3001/api/dashboard \
-H "Authorization: Bearer TOKEN"
# Criar tarefa
curl -X POST http://localhost:3001/api/tasks \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Implementar feature X","priority":"HIGH","status":"TODO"}'📱 Features da Aplicação
- ✅ Autenticação completa (registro, login, logout, refresh token automático)
- ✅ Dashboard agregado com stats em tempo real
- ✅ CRUD completo de tarefas com filtros e paginação
- ✅ Sistema de notificações em tempo real
- ✅ Perfil do usuário editável
- ✅ BFF Web otimizado para React.js
- ✅ BFF Mobile com payloads enxutos para React Native
- ✅ Redux Toolkit com thunks para gerenciamento de estado
- ✅ Interceptor de token refresh automático (sem logout ao expirar)
- ✅ Rate limiting por IP
- ✅ Validação de dados com Zod em todos os serviços
- ✅ Health checks em todos os serviços


