10 - La Forja en Spring Boot
El contrato diseñado a mano en el paso 09 se implementa: La Forja pasa de consola a API REST con Spring Boot. Las capas del paso 08 se quedan (negocio, persistencia, modelo); lo que cambia es la capa de presentación, que en vez de menú de consola atiende HTTP.
1. Qué se pide
- El proyecto Spring Boot con la dependencia web (desde Spring Initializr), con tu paquete base y las capas 08 trasladadas.
- Los controladores que implementan la tabla del paso 09 fila a fila: cada endpoint con su método, su ruta y el código de estado prometido — sin inventar nuevas rutas ni respuestas: si el contrato se había de cambiar, se discute y se cambia en el contrato primero.
- Las excepciones de negocio del paso 05 ya no se capturan a mano: vuelan hasta una clase única de manejo global que las traduce a los estados HTTP de la tabla de fallos de 09 — y cada traducción lleva el cuerpo de error previsto.
- Los
IO.printlnde los sucesos relevantes pasan a logs (fachada SLF4J), con niveles elegidos y sin datos sensibles en los mensajes. - Todas las filas del contrato se comprueban con curl como abajo.
2. Con qué
- Todo lo del tema: el DispatcherServlet como front controller, controladores anotados (
@RestController,@GetMapping…),ResponseEntitypara el cuerpo y el estado de cada respuesta, el contenedor de IoC (que ocupa el lugar del ensamblado manual del 08) y el manejo global de excepciones (@RestControllerAdvice). - El reparto de anotaciones es el del tema: el controlador en la presentación, el servicio en el negocio, el repositorio en la persistencia — cada una con la anotación de estereotipo que toque.
3. Decisiones tuyas
- ¿Cómo lee el controlador lo que le llega del cliente (rutas identificadas, cuerpo del POST, parámetro del filtro)? Cada fila del contrato se traduce a una firma de método.
- ¿En qué filas del contrato devuelves cuerpo y en cuáles no? El estado y el cuerpo son dos decisiones separadas.
- ¿Cómo decide el manejador global qué estado le toca a cada excepción? Y ¿el error no previsto qué estado promete y qué revela al cliente?
- ¿Qué entra en el log de cada suceso importante y con qué nivel? ¿Y qué relación hay entre los niveles de los fallos
4xxy5xx? - ¿Dónde vive el registro de cada suceso (acceso, error, arranque)? Decide el punto y defiende el criterio.
4. Comprobación
Con curl, cada fila del contrato, probada en orden:
- El listado de héroes y las fichas se devuelven con los códigos prometidos, y en un JSON que se lee.
- Se registra un héroe: el código de promesa llega y, si llevaba cuerpo, el héroe creado con su id del negocio.
- Una ficha inexistente devuelve el código de la tabla de fallos y su cuerpo de error, sin mensaje de máquina.
- Registrar con datos imposibles (nivel negativo, campo faltante) devuelve el código del contrato y el cuerpo de error construido desde la excepción.
- Un error no previsto (el que produce el manejo global por si acaso) devuelve
500: el detalle queda en el log, no en la respuesta. - En los logs: cada registro relevante aparece con su nivel y ninguno incluye datos sensibles.
- El programa compila sin capas cruzadas: la causa raíz de cada fallo queda dónde toca.
5. Pendientes
- El estado del repositorio en memoria es único, y ahora cada petición a la vez vive en su hilo → concurrencia (11).
- Cualquiera puede borrar héroes: falta saber quién consulta y qué puede hacer → tokens (12).