10 de Setembro de 2025
Handler, use case e repository: onde cada decisão deve morar
Muita base backend degrada porque transporte, regra e persistência ficam misturados no mesmo lugar sem ninguém admitir isso.
Andrews Ribeiro
Founder & Engineer
4 min Intermediario Sistemas
O problema
Muita arquitetura backend parece organizada só até a segunda mudança real.
No começo existe:
- handler
- service
- use case
- repository
Mas, na prática, cada camada vai pegando um pouco de tudo.
Aí aparece o clássico:
- handler validando, decidindo e persistindo
- use case repassando chamada sem agregar nada
- repository tomando decisão de negócio
- service conhecendo
statusCode, SQL e regra ao mesmo tempo
O resultado não é “arquitetura pragmática”.
É fronteira borrada.
Modelo mental
Essas camadas não existem para cumprir diagrama.
Elas existem para separar perguntas diferentes:
- quem recebe input externo?
- quem interpreta contrato de entrada?
- quem decide a regra principal?
- quem fala com banco ou provider?
- quem traduz o resultado de volta para o mundo externo?
Uma divisão simples costuma funcionar bem:
- handler: transporte
- use case: regra e orquestração
- repository: persistência
Não é religião.
Mas, quando isso está minimamente claro, a base fica mais legível.
Onde cada decisão costuma morar
Handler
Handler normalmente é dono de:
- receber request
- validar formato básico
- autenticar ou checar contexto
- traduzir erro e sucesso para o protocolo de entrada
O que ele não deveria carregar por padrão:
- regra principal de negócio
- SQL
- estratégia de retry
- decisão de domínio sobre status, fluxo ou transição
Em frase curta:
handler conversa com o mundo de fora
Use case
Use case é um bom lugar para:
- coordenar o fluxo principal
- aplicar regra de negócio
- decidir ordem das operações
- chamar repositórios e integrações com critério
Esse costuma ser o lugar certo para perguntas como:
- pode criar esse pedido?
- pode aprovar agora ou precisa pendenciar?
- quando deve cobrar, reservar ou publicar evento?
Em frase curta:
use case decide o que o sistema quer fazer
Repository
Repository deveria ser mais humilde do que muita base deixa.
Ele tende a cuidar de:
- leitura e escrita
- consulta orientada ao modelo persistido
- tradução entre objeto interno e armazenamento
Repository normalmente não deveria decidir:
- se o pedido nasce
pendingouapproved - se pode cobrar ou não
- se o retry cabe ou não
Em frase curta:
repository sabe como guardar e buscar, não por que algo deve acontecer
Exemplo simples
Imagine um fluxo de criação de pedido.
Uma versão ruim:
- handler recebe request
- handler checa estoque
- handler calcula frete
- handler cria pedido
- handler chama gateway
- handler decide erro de negócio
Agora imagine uma divisão melhor:
- handler valida o contrato de entrada
- use case decide se pode criar, qual status inicial usar e se pagamento entra agora ou depois
- repository grava pedido e itens
- gateway fala com provedor externo
- handler traduz o resultado em resposta HTTP
O ganho não é acadêmico.
É operacional.
Se o fluxo mudar, você sabe para onde olhar.
O erro oposto também existe
Tem time que aprende essa separação e exagera.
Cria:
- handler
- service
- use case
- manager
- orchestrator
- repository
- gateway
para um fluxo simples.
Isso também piora a base.
O objetivo não é multiplicar camadas.
É separar responsabilidade onde a mistura dói.
Como um senior pensa
Quem tem mais experiência costuma fazer a pergunta certa:
se essa regra mudar amanhã, onde eu gostaria que ela estivesse?
Essa pergunta vale mais do que seguir “clean architecture” no automático.
Porque o ponto real é diminuir:
- acoplamento
- efeito cascata
- dúvida em review
- dificuldade de teste
Ângulo de entrevista
Esse tema aparece muito quando perguntam:
- “onde você colocaria essa regra?”
- “como organizaria esse backend?”
- “o que fica no controller, service ou repository?”
Resposta forte não tenta impressionar pelo nome do padrão.
Ela mostra critério.
Algo como:
“Eu deixaria o handler responsável por contrato e protocolo. A regra principal ficaria no use case, e o repository esconderia persistência sem decidir negócio.”
Isso já passa a mensagem principal:
você separa camadas para tornar mudança previsível, não para colecionar abstrações
Resumo rápido
O que vale manter na cabeça
- Handler, use case e repository não existem para deixar pasta bonita; eles ajudam a separar tipos diferentes de decisão.
- Quando transporte, regra e persistência moram no mesmo arquivo, a mudança futura fica cara e imprevisível.
- Use case tende a concentrar a regra e a orquestração; repository tende a esconder detalhe de persistência, não decidir negócio.
- A melhor fronteira é a que torna a próxima mudança mais óbvia.
Checklist de pratica
Use isto ao responder
- Consigo dizer o que o handler decide e o que ele só encaminha?
- Meu use case está concentrando a regra principal ou virou só repasse?
- O repository está escondendo detalhes de banco ou está tomando decisão de negócio?
- Se a regra mudar amanhã, eu sei em qual camada esperaria mexer primeiro?
Você concluiu este artigo
Próximo passo
APIs e serviços com fronteiras claras Próximo passo →Compartilhar esta página
Copie o link manualmente no campo abaixo.