Service Layer
Definição (Fowler)
Seção intitulada “Definição (Fowler)”“Defines an application’s boundary with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation.”
O Service Layer é a fachada dos casos de uso. Ele coordena colaboradores (entidades, Repositórios, gateways), gerencia a fronteira transacional e traduz entre o mundo externo e o domínio.
Problema que resolve
Seção intitulada “Problema que resolve”Sem uma camada de aplicação explícita, a lógica de coordenação (transação, orquestração, autorização) vaza para a camada web (controllers) ou para o Domain Model. O Service Layer dá um lugar único e estável para essa coordenação, servindo múltiplos clientes (REST, mensageria, jobs) com a mesma API.
Quando usar
Seção intitulada “Quando usar”- Quando há mais de um cliente/canal consumindo a mesma lógica.
- Para demarcar transações e casos de uso de forma explícita.
- Como fronteira de segurança/autorização e de mapeamento DTO ↔ domínio.
Trade-offs
Seção intitulada “Trade-offs”| Vantagem | Custo |
|---|---|
| Fronteira transacional clara | Camada extra (mais indireção) |
| Casos de uso explícitos | Risco de virar “gerente” anêmico |
| Reuso entre canais | Pode duplicar contratos (DTOs) |
Quando NÃO usar (ou manter fino)
Seção intitulada “Quando NÃO usar (ou manter fino)”Em aplicações pequenas com um único cliente, o Service Layer pode ser tão fino que praticamente coincide com o controller. Nesse caso, mantenha-o mínimo — não force uma camada cerimoniosa.
Alerta central: onde a regra NÃO deve morar
Seção intitulada “Alerta central: onde a regra NÃO deve morar”O Service Layer coordena, não decide regra de domínio. Se as invariantes e cálculos migram para os serviços, o Domain Model vira anêmico e o serviço vira um Transaction Script disfarçado. A regra de negócio pertence às Entidades/Agregados ou a Domain Services quando não cabe numa única entidade.
graph TD
Controller[Controller / REST] --> SL[Service Layer]
SL -->|orquestra| DM[Domain Model]
SL -->|persiste| Repo[Repositórios]
SL -->|integra| GW[Gateway]
SL -.->|@Transactional| TX[(Transação)]
DM -->|contém a regra| DM
Exemplo Java/Spring
Seção intitulada “Exemplo Java/Spring”@Servicepublic class PedidoAppService {
private final PedidoRepository pedidos; private final EstoqueGateway estoque; private final PagamentoGateway pagamento;
public PedidoAppService(PedidoRepository pedidos, EstoqueGateway estoque, PagamentoGateway pagamento) { this.pedidos = pedidos; this.estoque = estoque; this.pagamento = pagamento; }
@Transactional public PedidoDTO confirmar(ConfirmarPedidoCommand cmd) { Pedido pedido = pedidos.findById(cmd.pedidoId()) .orElseThrow(() -> new PedidoNaoEncontradoException(cmd.pedidoId()));
estoque.reservar(pedido.getItens());
pedido.confirmar();
pagamento.cobrar(pedido.getTotal(), cmd.meioPagamento());
pedidos.save(pedido); return PedidoDTO.from(pedido); }}Repare: a decisão de poder confirmar (estado válido, itens presentes, total calculado) está em pedido.confirmar(), dentro do Domain Model. O serviço só orquestra a sequência, integra sistemas externos via Gateway e demarca a transação.
Anti-padrões e erros comuns
Seção intitulada “Anti-padrões e erros comuns”- Serviço gordo / domínio anêmico: regra de negócio migrando para o serviço.
- Transação larga demais:
@Transactionalcobrindo chamadas externas lentas (gateways), causando locks longos. - Vazar entidades para a web: retornar entidades JPA em vez de DTOs.
- Confundir com Domain Services: Domain Service contém regra que não cabe numa entidade; Service Layer (aplicação) apenas coordena.
- Duplicar validação: revalidar no serviço o que a entidade já garante.
Relações
Seção intitulada “Relações”- Orquestra o Domain Model e persiste via Repositórios.
- Materializa Use Cases da Clean Architecture (ver Camadas da Clean Architecture).
- É o mesmo conceito que o Application Service do DDD — as duas notas contam a mesma história com vocabulários de catálogos diferentes.
- Consome gateways como adapters secundários (Ports).
- Sobre um Transaction Script, o serviço contém a lógica; sobre um Domain Model, delega.
- Índice: PoEAA.
Perguntas de revisão
Seção intitulada “Perguntas de revisão”1. Qual é a responsabilidade essencial do Service Layer?
Resposta
Coordenar casos de uso: orquestrar objetos de domínio, delimitar a transação e mediar a integração com o exterior — sem conter a regra de negócio.
2. Como o Service Layer pode causar um domínio anêmico?
Resposta
Quando as invariantes e cálculos migram para os serviços em vez de morarem nas entidades/agregados. O domínio fica só com dados e o serviço vira um Transaction Script disfarçado.
3. Qual a diferença entre Service Layer e Domain Service?
Resposta
O Domain Service contém regra de domínio que não pertence naturalmente a uma única entidade; o Service Layer (aplicação) apenas coordena o fluxo do caso de uso e a transação.
4. Por que evitar transações longas no Service Layer?
Resposta
Porque envolver chamadas externas lentas dentro de @Transactional mantém locks e conexões abertos por muito tempo, prejudicando concorrência e escalabilidade.