Camadas típicas e responsabilidades:
- Controller / API layer (Web): expõe endpoints REST, valida entrada mínima.
- Service / Business layer: regras de negócio, orquestra chamadas, transações.
- Repository / Data Access layer: abstração do acesso a dados (Spring Data JPA).
- Domain / Model: entidades JPA e regras de domínio.
- Infra (opcional): integrações externas (gateway de pagamento, envio de SMS, storage).
graph TD
A["Controller / REST API"] --> B["Service / Business Rules"]
B --> C["Repository / Spring Data JPA"]
C --> D["Database (H2 / Postgres)"]
B --> E["Integrations (Payment, Notifications)"]
Boas práticas:
- Services são unit of work — concentre lógica transacional aqui.
- Repositórios apenas CRUD / queries; sem lógica de negócio.
- Separar DTOs para fronteira da API (ver tópico abaixo).
Contextualização: No Spring Boot, o MVC mapeia assim:
- Model: Entidades / DTOs.
- View: no REST, a view é JSON (representação).
- Controller: endpoints que recebem/retornam DTOs.
graph TD
A["Controller / REST API"] --> B["Service / Business Rules"]
B --> C["Repository / Spring Data JPA"]
C --> D["Database (H2 / Postgres)"]
B --> E["Integrations (Payment, Notifications)"]
Observação prática: para APIs, foque em Controllers finos, Services ricos.
Conceito: IoC = framework (Spring) gerencia a criação e injeção de objetos. DI = componentes recebem dependências via construtor, setter ou campo.
Vantagens:
- Testabilidade (mockar dependências).
- Baixo acoplamento.
- Reuso e configuração centralizada.
sequenceDiagram
Controller->>Service: chama operação()
Note right of Controller: Service foi injetado pelo Spring via construtor
Service->>Repository: consulta dados
Note right of Service: Repository injetado pelo Spring
Prática recomendada no Spring: usar injeção por construtor (favorece imutabilidade e testes).
Resumo objetivo:
- Entity (JPA): representa a tabela no banco — contém mapeamento ORM, relacionamento, lazy loading.
- DTO (Data Transfer Object): estrutura leve usada para comunicação (request/response). Não contém lógica de persistência.
Quando usar DTOs:
- Para proteger campos sensíveis (ex: senha, tokens).
- Para desacoplar API da estrutura interna (mudar Entity sem quebrar API).
- Para agrupar/simplificar dados (ex: resumo do restaurante com média de avaliações).
- Para validar entrada (usar
@Validem DTOs).
Fluxo típico (Mermaid)
graph LR
Client -->|JSON| Controller
Controller -->|map DTO->Entity| Service
Service --> Repository
Repository --> Database
Repository -->|Entity| Service
Service -->|map Entity->DTO| Controller
Controller -->|JSON| Client
Boas práticas e ferramentas:
- Mapear DTO ⇄ Entity com mapeadores (MapStruct ou ModelMapper) para evitar código repetido.
- Validar DTOs com
javax.validation(@NotNull,@Size, etc). - Não expor Entities diretamente em controllers (risco de lazy load exceptions e acoplamento).
- Definir e priorizar requisitos funcionais + não-funcionais.
- Desenhar ER e enumerações de status do pedido.
- Mapear endpoints REST para cada caso de uso.
- Estruturar projeto por camadas (controller/service/repository).
- Decidir quais objetos serão DTOs e quais serão Entities.
- Planejar integrações (pagamento, notificações) como adapters em infra.
- Configurar testes unitários para Services (mock de repos) e testes de integração com H2.