Microsserviços¶
Histórico: de monólitos a SOA, e de SOA a microsserviços¶
Definição: SOA (Service Oriented Architecture)
Estilo arquitetural que, em meados da década de 1990, propôs quebrar uma aplicação monolítica em serviços desacoplados, integrados por interfaces bem definidas e reutilizáveis — evitando integrações ponto a ponto difíceis de manter. O padrão técnico mais comum da época era SOAP em conjunto com WSDL (Web Service Definition Language), rodando sobre HTTP — o equivalente ao Nível 0 (The Swamp of POX) do modelo de maturidade REST.
flowchart LR
subgraph Monolito["Monólito"]
M["Uma única aplicação"]
end
subgraph SOA
S1["Aplicação<br/>de Catálogo"]
S2["Aplicação<br/>de Pedidos"]
S3["..."]
end
subgraph Microsservicos["Microsserviços"]
MS1["Produtos"]
MS2["Estoque"]
MS3["Mídia"]
MS4["..."]
end
Monolito -->|Desacopla módulos<br/>em aplicações| SOA
SOA -->|Especializa cada aplicação<br/>em serviços mais finos| Microsservicos
Definição: Microsserviços como evolução da SOA
A arquitetura de microsserviços manteve os conceitos fundamentais da SOA, mas foi além ao definir o tamanho ideal da unidade de software: em vez de uma aplicação por módulo de negócio, cada microsserviço deveria representar um único contexto de negócio, coeso e de baixo acoplamento — a mesma especialização que o SRP do SOLID já defendia na escala de classes, agora aplicada na escala de serviços inteiros.
Um exemplo prático dessa evolução: um módulo de "Catálogo" (que, dentro de um monólito de e-commerce, cuida de nome, descrição, preço, estoque e mídia de produtos ao mesmo tempo) fere o SRP ao concentrar vários domínios de negócio distintos no mesmo serviço. A especialização em microsserviços separaria essas responsabilidades em serviços próprios — Produtos (ciclo de vida do produto), Estoque (disponibilidade e movimentações) e Mídia (imagens e vídeos vinculados) — cada um coeso, autônomo e com baixo acoplamento entre si.
Integração de sistemas na Web: SOAP, SOA e REST¶
Sistemas isolados envelhecem mal: o mercado caminha para muitos sistemas pequenos que se integram. A integração pela Web usa HTTP (porta 80/443 aceita por firewalls e suportada por infinitas ferramentas) e passou por três grandes gerações:
| Geração | Ideia | Característica |
|---|---|---|
| POX / XML-RPC | XML "puro" sobre HTTP, com chamadas de método | Simples; cada sistema inventa seu formato |
| SOAP + WSDL | Contrato formal (WSDL descreve operações, tipos e endpoints), mensagens em envelopes XML | Padronizado e rígido; gera dezenas de classes por stubs; HTTP usado só como "túnel" |
| REST / JSON | Recursos com URIs, verbos HTTP e representações (JSON/XML) | Leve, aproveita o HTTP, melhor para evoluir |
Contratos rígidos x acoplamento¶
O WSDL dá segurança (tudo é descrito e validável), mas acopla cliente e servidor a uma estrutura completa: um
campo novo ou uma operação alterada exige reanalisar o WSDL e regenerar classes. A versão 1.2 do SOAP se
aproximou do HTTP (por exemplo, aceitando o GET), mas o modelo de "tudo é um método remoto" permaneceu. A lição vale
para qualquer integração: quanto mais genérico o cliente, menos manutenção.
- Validar só o que se usa: o consumidor valida apenas os campos de que precisa e ignora o resto, em vez de rejeitar o documento inteiro por um campo novo (padrão Must Ignore / tolerant reader).
- Produzir conforme o contrato: quem envia segue o esquema à risca.
- Valores padrão para campos novos ausentes em versões antigas.
- Janela de compatibilidade: o servidor se compromete a manter a versão antiga por um prazo (ex.: dois anos), avisa a depreciação e depois remove (Compatibilidade e evolução de contratos).
Princípios do SOA¶
Definição: SOA (princípios)
O SOA Manifesto define SOA como um estilo arquitetural independente de tecnologia: dá para implementá-lo com SOAP, REST, mensageria ou até CORBA. O que importa são os princípios, não o protocolo.
| Princípio | Significa |
|---|---|
| Granularidade adequada e reúso | Serviços com tamanho que permita vários clientes e a composição de novos serviços a partir dos existentes |
| Contrato formal e descoberta | O serviço é descrito (WSDL, OpenAPI) e localizável |
| Abstração da implementação | O cliente não conhece linguagem, banco nem detalhes internos |
| Baixo acoplamento | Cliente e serviço evoluem de forma independente |
| Composição e orquestração | Processos de negócio combinam serviços (BPEL; hoje Sagas e workflows) |
| Autonomia e governança | Cada serviço controla seus dados; regras comuns de segurança, versionamento e monitoramento |
Os microsserviços herdam esses princípios e restringem o tamanho ao contexto de negócio (acima).
REST e hipermídia (ROA)¶
REST organiza a integração em recursos identificados por URIs e manipulados por representações (HTML, XML, JSON). A arquitetura orientada a recursos (ROA) destaca:
- Hipermídia como controle: a resposta traz links (
rel="pagamentos") que dizem ao cliente o que ele pode fazer em seguida, em vez de o cliente conhecer todas as URIs de antemão (early binding). O servidor pode mudar URIs sem quebrar quem segue os links, e o fluxo do processo pode ser distribuído entre vários serviços (HATEOAS). - Relações (
rel) com nome único (URI própria ou valor registrado no IANA) evitam ambiguidade. - Media types declaram formato e semântica no cabeçalho (
Content-Type,Accept); o servidor responde406ou415quando não consegue atender. - Códigos HTTP descrevem o resultado (200, 201, 400, 404, 409...) em vez de códigos próprios no corpo.
- URI templates (
/clientes/{id}) documentam padrões de URI; no Java, a especificação JAX-RS (e o Spring MVC) mapeia métodos a esses recursos.
Comparado ao SOAP, REST reduz o acoplamento, mas exige disciplina de contrato (OpenAPI) e de versionamento.
Por que os microsserviços surgiram¶
Microsserviços não nasceram de uma preferência técnica abstrata — surgiram como resposta a um problema concreto de escala organizacional. Com a abundância de capital de investimento disponível para empresas de tecnologia (impulsionada pelo crescimento do mercado de Venture Capital), grandes empresas passaram a construir serviços cada vez maiores, e isso demandava times cada vez maiores para mantê-los.
Definição: Regra das duas pizzas
Heurística (popularizada pela Amazon) de que um time de desenvolvimento não deveria ser maior do que o número de pessoas que duas pizzas conseguem alimentar — em geral, algo entre 6 e 10 pessoas. Times maiores que isso tendem a gastar mais energia em coordenação (reuniões, alinhamento) do que em entrega — a comunicação cresce mais rápido que a produtividade.
Ao limitar o tamanho de cada time, uma aplicação monolítica grande demais para um time pequeno cuidar sozinho passou a precisar ser dividida — cada serviço menor sob responsabilidade de um time dentro do limite das duas pizzas. Essa divisão é a origem prática dos microsserviços: não uma escolha arquitetural isolada, mas uma consequência de como organizar o trabalho de várias equipes pequenas numa aplicação grande.
Definição: O custo dos microsserviços
Dividir um sistema em serviços menores resolve o problema de escala de time, mas introduz um custo novo: cada serviço agora precisa se comunicar com outros serviços através da rede (ver HTTP), em vez de uma simples chamada de método dentro do mesmo processo. Isso multiplica o número de interações do sistema, cada uma sujeita a latência de rede e falha parcial — foi dessa complexidade nova que nasceu toda uma área de padrões próprios de sistemas distribuídos (circuit breaker, service discovery, API Gateway, entre outros), necessários justamente para lidar com o que a divisão em microsserviços passou a exigir.
Benefícios e desafios¶
Nem sempre microsserviços são a melhor opção para um projeto — não são "balas de prata". Uma pesquisa da IBM com mais de 1.200 desenvolvedores e executivos apontou que 87% dos usuários sentiram que a implementação da arquitetura foi benéfica economicamente, mas os desafios também são reais e precisam ser avaliados.
| Categoria | Aspecto | Descrição resumida |
|---|---|---|
| Benefício | Independência | Isolamento entre microsserviços evita impactos e facilita manutenção |
| Benefício | Autonomia de equipes | Equipes pequenas podem cuidar de um microsserviço específico com mais domínio e agilidade |
| Benefício | Curva de aprendizado | Escopos menores são mais fáceis de entender para novos desenvolvedores |
| Benefício | Eficiência tecnológica | Uso de linguagens, bancos e ferramentas mais adequadas a cada microsserviço |
| Benefício | Escalabilidade pontual | Permite escalar apenas os microsserviços com maior demanda |
| Benefício | Manutenção facilitada | Alta coesão e baixo acoplamento tornam mudanças mais simples |
| Desafio | Migração do monólito | Transição direta é arriscada; o ideal é migrar gradualmente |
| Desafio | Complexidade de integração | Múltiplas dependências e risco de quebra entre microsserviços |
| Desafio | Testes e validação | Alta necessidade de automação para garantir estabilidade |
| Desafio | Monitoramento e logs | Exige centralização e rastreamento com identificadores únicos |
| Desafio | Depuração | Depuração local limitada; demanda uso de mocks e automações |
Definição: Depuração (debugging) distribuída
Depurar remotamente um ambiente de IDE local não é viável (e não funciona) com dezenas ou centenas de microsserviços — não existe, até hoje, uma resposta única sobre como fazer isso bem. A mitigação prática é investir em automação e mapeamento claro das entradas e saídas de cada microsserviço, usando mocks para as saídas — permitindo depurar em ambiente de desenvolvimento e identificar problemas na implementação de um microsserviço isoladamente.
Definição: Migração gradual, nunca direta
Caso a empresa já possua um monólito em produção, migrar a aplicação inteira de uma vez para microsserviços é arriscado e trabalhoso. A recomendação é uma estratégia gradual: iniciar a adoção da nova arquitetura em funcionalidades novas, migrando o restante do sistema aos poucos — dando tempo para o time (e o próprio software) amadurecerem tanto na arquitetura quanto no domínio.
Derivando microsserviços a partir de Agregados do DDD¶
O DDD já orienta a separação de Agregados como módulos dentro de uma aplicação monolítica — o passo seguinte é aplicar esse mesmo raciocínio para definir cada Agregado como um ou mais microsserviços, com ciclo de vida independente, baixo acoplamento e alta coesão.
| Agregado | Microsserviço |
|---|---|
| Pagamentos | payment-service |
| Clientes | customer-service |
| Salas | room-service |
| Eventos | event-service |
| Ingressos | ticket-service |
| Administrador | admin-service |
Definição: Um Agregado pode virar mais de um microsserviço
O relacionamento entre Agregados também pode se desdobrar em microsserviços novos —
por exemplo, o relacionamento do Agregado Pagamentos com o Agregado Cliente ("possui
ingressos de sessões") revela, na prática, um pedido de compra: daí surge um
microsserviço adicional, order-service, responsável só por criar e gerenciar
pedidos, sem realizar pagamento nem a gestão de ingressos em si — essas
responsabilidades continuam com payment-service e ticket-service,
respectivamente.
Definição: BFF (Backend For Frontend)
Padrão em que uma camada intermediária (aqui, bff-frontend) orquestra as chamadas a
vários microsserviços em sequência, manipula as respostas, e conhece o domínio
interno da aplicação — o objetivo é que o frontend nunca precise conhecer nem lidar
diretamente com toda essa complexidade de orquestração, falando só com o BFF. Nem
sempre é necessário um serviço dedicado a esse papel: em contextos mais simples, o
próprio customer-service/admin-service pode assumi-lo diretamente, já que ambos
naturalmente funcionam como porta de entrada para as jornadas do usuário.
Definição: BFF por canal x BFF por domínio
Duas formas comuns de modelar um BFF. Por canal: um BFF por tipo de frontend
(bff-web, bff-mobile), cada um otimizado para as necessidades específicas daquele
canal (formato de dados, latência) — se assemelha à arquitetura monolítica, pois
tende a acumular mais responsabilidades por ser a porta de entrada de todo um canal.
Por domínio: BFFs especializados por domínio de negócio (bff-customer,
bff-order), usados quando o mesmo frontend atende a diversos clientes/jornadas —
se assemelha mais à própria arquitetura de microsserviços, pois cada BFF atende um
grupo reduzido de jornadas. Nenhuma das duas abordagens é sempre certa: a escolha
depende da complexidade e dos objetivos do projeto, e é comum uma abordagem mista
(ex.: bff-home-header, bff-home-content) quando uma única jornada já é grande
o bastante para justificar sua própria divisão.
Definição: Vantagens, desafios e segurança do BFF
Vantagens: melhoria na experiência do usuário (dados já formatados para o frontend, menos lógica no cliente); menos chamadas de rede (consolida requisições, reduz latência); desacoplamento entre frontend e backend; facilidade de manutenção (mudar o backend sem afetar o frontend); flexibilidade para adaptar-se a novas tecnologias e dispositivos; escalonamento independente de cada BFF conforme a demanda.
Desafios: sobrecarga de múltiplos BFFs para manter; duplicação de lógica entre BFFs mitigável com libs compartilhadas; complexidade de integração com sistemas legados; necessidade de testes e CI/CD reforçados para evitar quebras; ponto único de falha por trás de cada BFF, exigindo gerenciamento de mudanças cuidadoso.
Segurança: como todo tráfego de um canal passa pelo BFF, ele se torna um ponto natural para concentrar preocupações de segurança — autenticação/autorização via OAuth2/JWT, proteção contra ataques comuns (Web Application Firewall, prevenção a SQL Injection e XSS), monitoramento em tempo real, e controle de dados sensíveis com políticas de acesso e auditoria.
Identificando os fluxos sistêmicos¶
Com os microsserviços mapeados, o próximo passo é identificar os fluxos sistêmicos — sequências de chamadas entre microsserviços necessárias para completar uma jornada de negócio. No sistema de gestão de eventos e venda de ingressos, três fluxos principais:
flowchart TD
BFF["bff-frontend"] -->|"Criação e gestão<br/>de eventos"| Admin["admin-service"]
Admin --> Event["event-service"]
Event -->|"Obtém salas/cadeiras<br/>disponíveis"| Room["room-service"]
Event -->|"Obtém ingressos<br/>disponíveis"| Ticket["ticket-service"]
flowchart TD
BFF["bff-frontend"] -->|"Cria o pedido de<br/>compra dos ingressos"| Customer["customer-service"]
Customer --> Order["order-service"]
Customer --> Event["event-service"]
Event --> Ticket["ticket-service"]
Order --> Room["room-service"]
flowchart TD
BFF["bff-frontend"] -->|"Paga o pedido de<br/>compra dos ingressos"| Customer["customer-service"]
Customer --> Payment["payment-service"]
Payment --> Order["order-service"]
Cada fluxo mostra como o bff-frontend delega a operação de entrada para o microsserviço
responsável, que então coordena os demais microsserviços necessários para completar a
jornada — gestão e listagem de eventos, criação de pedidos de compra, e pagamento de
pedidos, respectivamente. Mapear esses fluxos antes de implementar qualquer código deixa
explícitas as dependências entre microsserviços, o que ajuda a antecipar onde a
comunicação síncrona (REST) pode se beneficiar de comunicação assíncrona (ver
Event-Driven Architecture) para reduzir
acoplamento entre os fluxos.