TP3.2 — Aplicação CRUD Completa (Modo Autônomo)
Este TP retoma exatamente o mesmo enunciado do TP3.1, mas sem nenhum código fornecido. Você deve realizar tudo por conta própria. Se ficar bloqueado, consulte o TP3.1 como referência.
Duração estimada: 2h a 3h
Pré-requisitos: Ter compreendido os conceitos do Módulo 3 (arquitetura em camadas, Spring Data JPA, API REST)
Contexto
Você é desenvolvedor backend em uma escola. Foi solicitado que você crie uma API REST para gestão de estudantes com Spring Boot.
O que você deve entregar
Etapa 1 — Criar o projeto Spring Boot
- Crie um novo projeto Spring Boot via Spring Initializr
- Escolha as dependências necessárias para:
- Criar uma API REST
- Utilizar um banco de dados em memória (H2)
- Fazer persistência JPA
- Validar os dados de entrada
Etapa 2 — Criar a entidade Student
Crie uma entidade Student com os seguintes campos:
| Campo | Tipo | Restrições |
|---|---|---|
| id | Long | Chave primária, auto-gerada |
| firstName | String | Obrigatório, entre 2 e 50 caracteres |
| lastName | String | Obrigatório, entre 2 e 50 caracteres |
| String | Obrigatório, formato de e-mail válido, único | |
| age | Integer | Obrigatório, entre 18 e 100 |
| program | String | Obrigatório (ex: "Informática", "Engenharia de Software") |
Etapa 3 — Criar o Repository
- Crie uma interface Repository para a entidade
Student - Adicione um método para verificar se um e-mail já existe
- Adicione um método para buscar estudantes por programa
Etapa 4 — Criar o Service
Crie um Service que implemente a seguinte lógica de negócio:
- Recuperar todos os estudantes
- Recuperar um estudante pelo seu ID — se o estudante não existir, lançar uma exceção apropriada
- Criar um estudante — verificar se o e-mail já não está sendo utilizado antes de salvar. Se o e-mail já existir, retornar um erro 409 (Conflict)
- Editar um estudante — verificar se o estudante existe, então atualizar suas informações
- Excluir um estudante — verificar se o estudante existe, então removê-lo
Etapa 5 — Criar o Controller REST
Crie um Controller que exponha os seguintes endpoints:
| Método HTTP | URL | Ação | Código de retorno esperado |
|---|---|---|---|
| GET | /api/students | Lista de todos os estudantes | 200 OK |
| GET | /api/students/\{id\} | Detalhe de um estudante | 200 OK ou 404 Not Found |
| POST | /api/students | Criar um estudante | 201 Created ou 409 Conflict |
| PUT | /api/students/\{id\} | Editar um estudante | 200 OK ou 404 Not Found |
| DELETE | /api/students/\{id\} | Excluir um estudante | 204 No Content ou 404 Not Found |
- Os dados enviados em POST e PUT devem ser validados automaticamente
- Se a validação falhar, retornar o código 400 Bad Request
Etapa 6 — Configurar o banco de dados H2
- Configure a aplicação para usar um banco de dados H2 em memória
- Ative o console H2 para poder visualizar os dados no navegador
- O console deve ser acessível na URL
/h2-console
Etapa 7 — Testar todos os endpoints
Teste sua API com Postman (ou ferramenta equivalente). Você deve realizar e capturar os seguintes testes:
- Criar 3 estudantes (POST) — verificar o código 201
- Listar todos os estudantes (GET) — verificar que existem 3
- Recuperar um estudante por ID (GET) — verificar os dados
- Editar um estudante (PUT) — alterar seu programa, verificar a atualização
- Excluir um estudante (DELETE) — verificar o código 204
- Relistar todos os estudantes — verificar que restam apenas 2
- Testar erros:
- GET em um ID inexistente → 404
- POST com um e-mail já utilizado → 409
- POST com um e-mail inválido → 400
- POST com nome vazio → 400
Exercícios bônus
Bônus 1 — Busca por programa
Adicione um endpoint que permita buscar estudantes por programa:
GET /api/students/program/{program}
Por exemplo: GET /api/students/program/Informática retorna todos os estudantes de Informática.
Bônus 2 — Estatísticas
Adicione um endpoint que retorne estatísticas:
GET /api/students/stats
O JSON retornado deve conter:
- O número total de estudantes
- A média de idade
- O número de estudantes por programa
Bônus 3 — Paginação
Modifique o endpoint GET /api/students para suportar paginação:
GET /api/students?page=0&size=10&sort=lastName
Bônus 4 — Gestão centralizada de erros
Crie um handler global de exceções que:
- Retorne mensagens de erro claras em JSON
- Trate os casos: estudante não encontrado (404), e-mail duplicado (409), validação falhou (400)
Formato esperado da resposta de erro:
{
"status": 404,
"message": "Estudante não encontrado com o ID: 99",
"timestamp": "2025-01-15T10:30:00"
}
Bônus 5 — Migração para PostgreSQL
Substitua o H2 por PostgreSQL:
- Crie um banco de dados
studentdbno PostgreSQL - Modifique a configuração para apontar para o PostgreSQL
- Verifique que os dados persistem após reiniciar a aplicação
Entregáveis
| # | Entregável | Formato |
|---|---|---|
| 1 | Código-fonte completo do projeto | Repositório Git ou ZIP |
| 2 | Capturas de tela do Postman dos 10 testes (7 + 3 erros) | Imagens |
| 3 | Captura de tela do console H2 com dados | Imagem |
| 4 | Pelo menos 2 exercícios bônus completos | Código |
| 5 | Respostas às perguntas de revisão (abaixo) | Documento de texto |
Perguntas de revisão
Responda a estas perguntas com suas próprias palavras:
- Qual é a responsabilidade de cada camada (Controller, Service, Repository)?
- Por que separamos o código em camadas distintas?
- Qual a diferença entre
@RestControllere@Service? - Como o Spring Data JPA gera as queries SQL automaticamente?
- Qual código HTTP deve ser retornado após uma criação bem-sucedida? E após uma exclusão?
- Por que verificar a unicidade do e-mail no Service e não apenas no banco de dados?
- O que acontece se enviarmos um JSON inválido para o Controller?
- Qual a diferença entre
findById()que retorna umOptionale um método que retorna diretamente o objeto?
Critérios de avaliação
| Critério | Pontos |
|---|---|
| Arquitetura em camadas corretamente implementada (Controller → Service → Repository) | 20% |
| Entidade Student com todas as validações | 15% |
| Repository com métodos personalizados | 10% |
| Service com lógica de negócio completa (verificações, exceções) | 20% |
| Controller com os 5 endpoints CRUD funcionais | 20% |
| Testes Postman bem-sucedidos (casos normais + casos de erro) | 10% |
| Exercícios bônus | 5% |
| Total | 100% |
Se você ficar bloqueado, não permaneça mais de 15 minutos em um problema. Consulte o TP3.1 para ver como foi feito, depois volte aqui e tente refazer sem olhar.