Um sistema completo de gerenciamento de clientes desenvolvido em Spring Boot, implementando operações CRUD (Create, Read, Update, Delete) com arquitetura REST.
Este projeto é uma API REST para gerenciamento de clientes, desenvolvida como parte de um desafio de programação. O sistema permite cadastrar, consultar, atualizar e excluir clientes através de endpoints RESTful.
- ✅ CRUD Completo: Criar, ler, atualizar e deletar clientes
- ✅ Paginação: Listagem de clientes com suporte a paginação
- ✅ Validação: Validação de dados de entrada com mensagens personalizadas
- ✅ Tratamento de Erros: Sistema robusto de tratamento de exceções
- ✅ Banco H2: Banco de dados em memória para desenvolvimento/teste
- ✅ Dados de Teste: 16 clientes pré-cadastrados para demonstração
- Java 21
- Spring Boot 3.5.5
- Spring Data JPA
- Spring Web
- H2 Database (banco em memória)
- Jakarta Validation
- Hibernate Validator
- Maven (gerenciamento de dependências)
src/
├── main/
│ ├── java/com/desafio/crud/
│ │ ├── controllers/ # Controladores REST
│ │ │ ├── ClientController.java
│ │ │ └── handlers/
│ │ │ └── ControllerExceptionHandler.java
│ │ ├── dto/ # Data Transfer Objects
│ │ │ ├── ClientDTO.java
│ │ │ ├── CustomError.java
│ │ │ ├── FieldMessage.java
│ │ │ └── ValidationError.java
│ │ ├── entities/ # Entidades JPA
│ │ │ └── Client.java
│ │ ├── repositories/ # Repositórios de dados
│ │ │ └── ClientRepository.java
│ │ ├── services/ # Lógica de negócio
│ │ │ ├── ClientService.java
│ │ │ └── exceptions/
│ │ │ ├── DatabaseException.java
│ │ │ └── ResourceNotFoundException.java
│ │ └── CrudApplication.java # Classe principal
│ └── resources/
│ ├── application.properties
│ ├── application-test.properties
│ └── import.sql # Dados iniciais
- Java 21 ou superior
- Maven 3.6 ou superior
-
Clone o repositório:
git clone <url-do-repositorio> cd spring-boot-client-crud
-
Execute a aplicação:
./mvnw spring-boot:run
Ou no Windows:
mvnw.cmd spring-boot:run
-
Acesse a aplicação:
- API Base URL:
http://localhost:8080 - Console H2:
http://localhost:8080/h2-console
- API Base URL:
| Método | Endpoint | Descrição |
|---|---|---|
GET |
/clients |
Lista todos os clientes (com paginação) |
GET |
/clients/{id} |
Busca cliente por ID |
POST |
/clients |
Cria um novo cliente |
PUT |
/clients/{id} |
Atualiza um cliente existente |
DELETE |
/clients/{id} |
Remove um cliente |
GET http://localhost:8080/clients?page=0&size=10&sort=name,ascGET http://localhost:8080/clients/1POST http://localhost:8080/clients
Content-Type: application/json
{
"name": "João Silva",
"cpf": "12345678901",
"income": 5000.0,
"birthDate": "1990-05-15",
"children": 2
}PUT http://localhost:8080/clients/1
Content-Type: application/json
{
"name": "João Silva Santos",
"cpf": "12345678901",
"income": 6000.0,
"birthDate": "1990-05-15",
"children": 3
}DELETE http://localhost:8080/clients/1{
"id": 1,
"name": "João Silva",
"cpf": "12345678901",
"income": 5000.0,
"birthDate": "1990-05-15",
"children": 2
}- Nome:
@NotEmpty- Obrigatório e não pode estar vazio - Data de Nascimento:
@PastOrPresent- Não pode ser uma data futura
Nota: CPF, Renda e Número de Filhos são campos livres sem validação específica implementada.
- URL:
jdbc:h2:mem:testdb - Usuário:
sa - Senha: (vazia)
- Console:
http://localhost:8080/h2-console
O sistema já vem com 16 clientes pré-cadastrados para demonstração, incluindo dados como:
- João Ferreira, CPF: 10830410215, Renda: R$ 5.000,00
- Maria Oliveira, CPF: 32491877790, Renda: R$ 7.200,00
- Ana Souza, CPF: 14726593401, Renda: R$ 3.200,00
- E mais 13 clientes...
O sistema possui um tratamento robusto e personalizado de exceções com respostas padronizadas e estruturadas:
ResourceNotFoundException: Cliente não encontrado (404)DatabaseException: Erro de integridade referencial (400)MethodArgumentNotValidException: Dados inválidos (422)
O ControllerExceptionHandler centraliza o tratamento de todas as exceções:
@ControllerAdvice
public class ControllerExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<CustomError> resourceNotFound(...)
@ExceptionHandler(DatabaseException.class)
public ResponseEntity<CustomError> database(...)
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ValidationError> methodArgumentNotValid(...)
}- 200 OK: Operação realizada com sucesso
- 201 Created: Cliente criado com sucesso
- 204 No Content: Cliente deletado com sucesso
- 400 Bad Request: Erro de integridade referencial
- 404 Not Found: Cliente não encontrado
- 422 Unprocessable Entity: Dados inválidos
{
"timestamp": "2024-01-15T10:30:00Z",
"status": 404,
"error": "Recurso não encontrado",
"path": "/clients/999"
}{
"timestamp": "2024-01-15T10:30:00Z",
"status": 422,
"error": "Dados inválidos",
"path": "/clients",
"errors": [
{
"fieldName": "name",
"message": "O nome é obrigatório e não pode estar vazio"
},
{
"fieldName": "birthDate",
"message": "A Data de nascimento não pode ser no futuro"
}
]
}CustomError: Estrutura base para erros simplesValidationError: Herda deCustomError+ lista de erros de campoFieldMessage: Representa um erro específico de campo
Nota: Este é um projeto de demonstração usando banco H2 em memória. Os dados são perdidos quando a aplicação é reiniciada.