Série: Recolocação e teste prático Java

Episódio 05: Onde a regra acontece: services, casos de uso e separação de responsabilidades

Episódio 05: Application layer

Onde os testes práticos perdem pontos

Se existe um lugar onde muitos candidatos sangram, é o controller que virou aplicação inteira: if acumulado, repository na face HTTP, validação espalhada. O enunciado da recolocação foi explícito: controllers simples delegando à camada de aplicação.

Na visão geral, a camada de aplicação é o meio entre HTTP e persistência — onde a regra evita que o controller vire monólito:

Visão geral
Cliente REST API de veículos Persistência

A Application é o “meio” que impede o controller de virar monólito.

O problema por trás da etapa

A camada Application é onde vivem os casos de uso: cadastrar, atualizar, listar com paginação, obter por id e remover. Ela não precisa conhecer Swagger nem console H2; precisa executar operações do sistema de ponta a ponta.

Um VeiculoService coeso pode bastar; classes por caso de uso são opcionais. O PDF menciona CQRS como opcional — a palavra-chave é opcional: não inflar para impressionar.

No mesmo artefacto Spring Boot, o pacote Application é um bloco lógico de execução — transações e casos de uso sem novo deploy:

O que corre na máquina
Spring Boot
(runtime JVM)
Pacote Application
(casos de uso + transações)

Um único processo; a fronteira é modularização lógica, não rede.

A decisão técnica

Cadastro: dados já validados na borda viram nova entidade persistida. Atualização: buscar, tratar ausência, aplicar campos permitidos, salvar — isso não mora no controller nem “puro” no repository. Consulta por id: ausência vira exceção de aplicação (ex.: VeiculoNaoEncontradoException) que a Web traduz em 404.

Listagem paginada: parâmetros de página e tamanho com critério; @Transactional em escritas, leituras read-only quando fizer sentido. Transação orbita o caso de uso, não o controller.

Essas escolhas aparecem como blocos técnicos — service, portas, mapeamento e exceções de aplicação:

Componentes da solução
VeiculoService
ou casos de uso
Porta saída
repositório
DTO ↔ entidade
mapeamento fino
Exceções de aplicação
ex.: não encontrado

Cadastrar, atualizar, listar (paginado), obter, remover — cada operação com dono explícito.

Implementando com critério

Remoção: decidir se id inexistente retorna 404 de forma consistente; evitar deleteById cego sem verificar existência se a API promete resposta clara. Métodos do service na ordem mental dos endpoints ajudam o avaliador a ler em sequência.

Na organização do código, nomes de negócio e @Transactional no lugar certo contam a história em vertical:

Detalhe no código
cadastrar(...) atualizar(...) listar(Pageable) remover(id) + @Transactional

Métodos pequenos e nomes de negócio: a banca lê como história, não como lista de if.

Fechamento da etapa

Com Application sólida, os fluxos principais rodam sem que o formato HTTP seja a estrela — sinal de que a regra não depende do controller. Próximo episódio: porta HTTP fina, validação e Swagger.

Como defender essa etapa

Responda “onde o sistema faz o que promete?” — não no controller, não só no repository; nos casos de uso. Exceções de domínio da aplicação sem detalhe de HTTP mostram fronteira saudável.

Reflexão final: Service bem nomeado é cartão de visitas da arquitetura em prova de mesa.


Nota: Cenário anonimizado; série de insights técnicos reutilizáveis.

Christian Mulato
Engenheiro Construtor

© 2026 Christian Mulato. Todos os direitos reservados.