TP3.2 — Aplicación CRUD Completa (Modo Autónomo)
Este TP retoma exactamente el mismo enunciado que el TP3.1, pero sin ningún código proporcionado. Debe realizar todo por usted mismo. Si se queda bloqueado, consulte el TP3.1 como referencia.
Duración estimada: 2h a 3h
Prerrequisitos: Haber comprendido los conceptos del Módulo 3 (arquitectura en capas, Spring Data JPA, API REST)
Contexto
Usted es desarrollador backend en una escuela. Se le pide crear una API REST de gestión de estudiantes con Spring Boot.
Lo que debe entregar
Paso 1 — Crear el proyecto Spring Boot
- Cree un nuevo proyecto Spring Boot vía Spring Initializr
- Elija las dependencias necesarias para:
- Crear una API REST
- Utilizar una base de datos en memoria (H2)
- Realizar persistencia JPA
- Validar los datos de entrada
Paso 2 — Crear la entidad Student
Cree una entidad Student con los siguientes campos:
| Campo | Tipo | Restricciones |
|---|---|---|
| id | Long | Clave primaria, auto-generada |
| firstName | String | Obligatorio, entre 2 y 50 caracteres |
| lastName | String | Obligatorio, entre 2 y 50 caracteres |
| String | Obligatorio, formato de email válido, único | |
| age | Integer | Obligatorio, entre 18 y 100 |
| program | String | Obligatorio (ej: "Informática", "Ingeniería de software") |
Paso 3 — Crear el Repository
- Cree una interfaz Repository para la entidad
Student - Agregue un método para verificar si un email ya existe
- Agregue un método para buscar estudiantes por programa
Paso 4 — Crear el Service
Cree un Service que implemente la siguiente lógica de negocio:
- Recuperar todos los estudiantes
- Recuperar un estudiante por su ID — si el estudiante no existe, lanzar una excepción apropiada
- Crear un estudiante — verificar que el email no esté ya en uso antes de guardar. Si el email ya existe, retornar un error 409 (Conflict)
- Modificar un estudiante — verificar que el estudiante existe, luego actualizar su información
- Eliminar un estudiante — verificar que el estudiante existe, luego eliminarlo
Paso 5 — Crear el Controller REST
Cree un Controller que exponga los siguientes endpoints:
| Método HTTP | URL | Acción | Código de retorno esperado |
|---|---|---|---|
| GET | /api/students | Lista de todos los estudiantes | 200 OK |
| GET | /api/students/\{id\} | Detalle de un estudiante | 200 OK o 404 Not Found |
| POST | /api/students | Crear un estudiante | 201 Created o 409 Conflict |
| PUT | /api/students/\{id\} | Modificar un estudiante | 200 OK o 404 Not Found |
| DELETE | /api/students/\{id\} | Eliminar un estudiante | 204 No Content o 404 Not Found |
- Los datos enviados en POST y PUT deben ser validados automáticamente
- Si la validación falla, retornar un código 400 Bad Request
Paso 6 — Configurar la base de datos H2
- Configure la aplicación para utilizar una base de datos H2 en memoria
- Active la consola H2 para poder visualizar los datos en el navegador
- La consola debe ser accesible en la URL
/h2-console
Paso 7 — Probar todos los endpoints
Pruebe su API con Postman (o una herramienta equivalente). Debe realizar y capturar las siguientes pruebas:
- Crear 3 estudiantes (POST) — verificar el código 201
- Listar todos los estudiantes (GET) — verificar que hay 3
- Recuperar un estudiante por ID (GET) — verificar los datos
- Modificar un estudiante (PUT) — cambiar su programa, verificar la actualización
- Eliminar un estudiante (DELETE) — verificar el código 204
- Relistar todos los estudiantes — verificar que solo quedan 2
- Probar los errores:
- GET sobre un ID inexistente → 404
- POST con un email ya utilizado → 409
- POST con un email inválido → 400
- POST con un nombre vacío → 400
Ejercicios bonus
Bonus 1 — Búsqueda por programa
Agregue un endpoint que permita buscar estudiantes por programa:
GET /api/students/program/{program}
Por ejemplo: GET /api/students/program/Informática retorna todos los estudiantes en Informática.
Bonus 2 — Estadísticas
Agregue un endpoint que retorne estadísticas:
GET /api/students/stats
El JSON retornado debe contener:
- El número total de estudiantes
- El promedio de edad
- El número de estudiantes por programa
Bonus 3 — Paginación
Modifique el endpoint GET /api/students para soportar paginación:
GET /api/students?page=0&size=10&sort=lastName
Bonus 4 — Gestión centralizada de errores
Cree un manejador global de excepciones que:
- Retorne mensajes de error claros en formato JSON
- Gestione los casos: estudiante no encontrado (404), email duplicado (409), validación fallida (400)
Formato de respuesta de error esperado:
{
"status": 404,
"message": "Estudiante no encontrado con el ID: 99",
"timestamp": "2025-01-15T10:30:00"
}
Bonus 5 — Migración a PostgreSQL
Reemplace H2 por PostgreSQL:
- Cree una base de datos
studentdben PostgreSQL - Modifique la configuración para apuntar a PostgreSQL
- Verifique que los datos persisten después de reiniciar la aplicación
Entregables
| # | Entregable | Formato |
|---|---|---|
| 1 | Código fuente completo del proyecto | Repositorio Git o ZIP |
| 2 | Capturas de pantalla de Postman de las 10 pruebas (7 + 3 errores) | Imágenes |
| 3 | Captura de pantalla de la consola H2 con datos | Imagen |
| 4 | Al menos 2 ejercicios bonus completados | Código |
| 5 | Respuestas a las preguntas de repaso (abajo) | Documento de texto |
Preguntas de repaso
Responda estas preguntas con sus propias palabras:
- ¿Cuál es la responsabilidad de cada capa (Controller, Service, Repository)?
- ¿Por qué se separa el código en capas distintas?
- ¿Cuál es la diferencia entre
@RestControllery@Service? - ¿Cómo genera Spring Data JPA las consultas SQL automáticamente?
- ¿Qué código HTTP se debe retornar después de una creación exitosa? ¿Después de una eliminación?
- ¿Por qué verificar la unicidad del email en el Service y no solo en la base de datos?
- ¿Qué ocurre si se envía un JSON inválido al Controller?
- ¿Cuál es la diferencia entre
findById()que retorna unOptionaly un método que retorna directamente el objeto?
Criterios de evaluación
| Criterio | Puntos |
|---|---|
| Arquitectura en capas correctamente implementada (Controller → Service → Repository) | 20% |
| Entidad Student con todas las validaciones | 15% |
| Repository con métodos personalizados | 10% |
| Service con lógica de negocio completa (verificaciones, excepciones) | 20% |
| Controller con los 5 endpoints CRUD funcionales | 20% |
| Pruebas Postman exitosas (casos normales + casos de error) | 10% |
| Ejercicios bonus | 5% |
| Total | 100% |
Si se queda bloqueado, no permanezca más de 15 minutos en un problema. Consulte el TP3.1 para ver cómo está hecho, luego regrese aquí e intente hacerlo sin mirar.
⬅️ TP3.1: Arquitectura CRUD (guiado) | ⬅️ Volver al Módulo 3