Pular para o conteudo principal

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

Andrews Ribeiro

Founder & Engineer

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 pending ou approved
  • 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

Checklist de pratica

Use isto ao responder

Você concluiu este artigo

Próximo artigo Request síncrono, job assíncrono ou evento: como decidir sem ritual Artigo anterior Rollout vs experimento: quando medir, quando comparar, quando só liberar

Continue explorando

Artigos relacionados