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.

  • 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.println de 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.
  • Todo lo del tema: el DispatcherServlet como front controller, controladores anotados (@RestController, @GetMapping…), ResponseEntity para 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.
  • ¿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 4xx y 5xx?
  • ¿Dónde vive el registro de cada suceso (acceso, error, arranque)? Decide el punto y defiende el criterio.

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.
  • 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).
  • clase/daw/prog/2eval/practicas/p11.txt
  • Última modificación: 2026/10/29 10:07
  • por cesguiro