Arquitetura Hexagonal em Python: Isolando o Domínio para Aplicações Robustas e Escaláveis

A arquitetura hexagonal, ou Ports and Adapters, coloca a lógica de negócio no centro de um hexágono simbólico, cercada por portas (interfaces abstratas) que conectam adaptadores externos como bancos de dados, APIs web, filas ou serviços de terceiros. Proposta por Alistair Cockburn em 2005, ela inverte as dependências tradicionais: o domínio não conhece frameworks ou persistência, mas estes dependem dele via injeção de dependências, promovendo código limpo e adaptável em Python. Essa abordagem alinha-se perfeitamente à filosofia “simples é melhor” do Python, mas com rigor para domínios complexos.

Componentes e Fluxo de Dados

O domínio abriga entidades imutáveis, agregados e regras puras, livres de anomalias arquiteturais como dependências de frameworks ou bancos de dados. Portas de entrada definem casos de uso (ex.: CreateUserPort), enquanto portas de saída expõem repositórios abstratos (ex.: UserRepository). Adaptadores concretos — como FastAPI para HTTP ou SQLAlchemy para DB — implementam essas portas, garantindo que o core permaneça intocado por mudanças externas. O fluxo entra pelas bordas, atinge o domínio via portas e sai por adaptadores, criando uma barreira unidirecional contra acoplamento.

Vantagens em Aplicações Python

Desvantagens e Limitações

Casos de Uso Práticos em Python

Adote em microsserviços serverless. Útil em sistemas DDD como bibliotecas de gestão ou ERPs, isolando regras fiscais de persistência multi-DB. Evite em scripts ou MVPs rápidos; combine com Clean Architecture para monolitos legados. Exemplos reais incluem APIs de usuários com FastAPI, em que trocar mocks por Redis em produção é trivial.

Refatorando Projetos Existentes para Hexagonal

Refatorar monolitos Python para hexagonal exige abordagem incremental, priorizando estabilidade e testes. Siga estes passos práticos:

  1. Mapeie o Domínio Atual: Identifique entidades principais (ex.: User, Order) e regras de negócio misturadas em controllers/services. Extraia para domain/entities/ e domain/services/, criando dataclasses imutáveis.
  2. Defina Portas Mínimas: Para cada operação externa (DB, email, HTTP), crie interfaces ABC em domain/ports/ (ex.: UserRepository, EmailPort). Comece com 2-3 portas críticas.
  3. Crie Casos de Uso: Migre lógica de controllers para application/use_cases/ injetando portas. Exemplo: CreateUserUseCase(repo: UserRepository) orquestra validação e domínio.
  4. Implemente Adaptadores Gradualmente: Refatore controllers existentes para usar casos de uso (adaptadores de entrada). Crie infrastructure/repositories/ com implementações atuais (SQLAlchemy → PostgresUserRepository).
  5. Reestruture Pastas: Adote src/domain/, src/application/, src/infrastructure/. Use dependency-injector para wiring automático em main.py.
  6. Testes como Rede de Segurança: Escreva testes para portas/mock antes de refatorar, garantindo 100% de cobertura no domínio. Rode pytest em paralelo durante a migração.
  7. Migre por Feature: Refatore uma entidade por sprint (ex.: só User primeiro), mantendo código legado rodando via adaptadores híbridos.youtube​

Use a ferramenta radon para monitorar a complexidade ciclomática do código (ex.: radon cc src/). Se a média subir acima de 10 ou o ROI (retorno sobre investimento) cair — medido por testes mais lentos ou refatorações frequentes —, pause a migração. Projetos grandes (>10k linhas de código) recuperam o investimento em 3-6 meses com testes mais rápidos e manutenção simplificada; para projetos pequenos (<5k linhas), calcule o custo-benefício antes de prosseguir.

Conclusão: Adote Hexagonal e Eleve Seu Código

A arquitetura hexagonal transforma aplicações Python em sistemas resilientes, testáveis e evolutivos, isolando o domínio de frameworks voláteis e promovendo baixa manutenção a longo prazo. Ideal para domínios complexos como ERPs ou microsserviços, ela equilibra a simplicidade zen do Python com escalabilidade enterprise.​

Pronto para refatorar? Comece hoje: pegue um módulo CRUD do seu projeto, extraia as portas em 1 hora e teste com pytest. Baixe repositórios de exemplo no GitHub, experimente em um branch e veja a diferença em testes isolados. Compartilhe conosco no Mastodon em @riverfount@bolha.us sua primeira vitória hexagonal — ou dúvidas para discutirmos.



Riverfount
Vicente Eduardo Ribeiro Marçal