====== 09 - La Forja: el contrato de la API ====== La presentación es la consola: un solo usuario, en el mismo ordenador, tecleando. El paso que viene la pondrá en **Spring Boot**; pero primero hay que diseñar el **contrato**: qué recursos existen, qué endpoints los atienden y qué código de estado devuelve cada caso. El paso es papel y lápiz. ===== 1. Qué se pide ===== * **Diseñar el contrato completo de la API** de La Forja y documentarlo en dos tablas tuyas: * la tabla de **endpoints**: recurso, ruta, método, acción que realiza y respuesta esperada (con su código de estado de éxito); * la tabla de **respuestas a los fallos**: cada situación que puede salir mal de la API (las excepciones del paso 05, datos inválidos, errores no previstos...) y su código. * El dominio de La Forja se expresa en **sustantivos en plural**; la acción la determina el **método HTTP**, no la URL. * Las mismas acciones que ya tiene la app (listar y ficha, registrar, retirar, filtrar la forja, equipar, informes) tienen su hueco en el contrato — pero tú decides su forma. * El contrato **no se implementa** aún: solo se diseña, como el pseudocódigo en el paso 01. Se implementará en el paso 10 tal y como quede escrito aquí. ===== 2. Con qué ===== * Todo lo del tema: anatomía de una URL, diseño de recursos y endpoints, métodos HTTP y su significado, **JSON** y, sobre todo, los **códigos de estado**: cómo se elige el que corresponde a cada situación. * Los datos que viajan en el cuerpo lo definen los **DTO records** del paso 08: el diseño elige cuáles son entrada y cuáles salida. Los cuerpos en JSON se serializan del record — el formato lo pone la librería, no tú: decide qué campos va a llevar cada uno. * Ejemplo del estilo de cuerpo que viaja (los campos los dictan tus DTO): { "nombre": "Aria", "clase": "MAGO", "nivel": 2 } { "id": 1, "nombre": "Aria", "clase": "MAGO", "nivel": 2, "poder": 15 } { "message": "No existe el héroe con id 99" } * Ojo con la escritura para quien va a consumir la API: los clientes razonan con el contrato, no con tu código. Nombres, rutas y cuerpos tienen que explicarse solos. ===== 3. Decisiones tuyas ===== * ¿Qué **recursos** has decidido y por qué? El plural y la ruta base (¿incluye la versión de la API?) son parte del contrato. * ¿Qué método HTTP atiende cada acción y qué código promete en éxito? Justifica el método con su significado, no con la costumbre. * ¿Cómo identifica al héroe la ruta: **path parameter**, **query parameter** o en el cuerpo? Y ¿cómo se expresa la relación entre héroe e ítem equipado (¿se anida la ruta o no)? * El filtro por rareza de la forja: ¿su propio endpoint o un parámetro? ¿Por qué? * ¿Qué código recibe cada fallo y qué cuerpo? Un héroe que no existe y un ítem que no existen: ¿misma respuesta o distinta? * ¿Se devuelve la ficha creada al registrar? ¿Y en cada fallo, un cuerpo de error con mensaje legible? ===== 4. Comprobación ===== * El contrato cubre todas las acciones actuales de la app, sin endpoints para cosas que no existen y sin acciones sin hueco. * Los 'status' de éxito de cada fila distinguen creación de consulta de acción sin cuerpo de respuesta; los de fallo distinguen esfuerzo del cliente de fallo del servidor. * Las rutas del contrato se pueden probar a mano con los ejemplos JSON sin ayuda adicional: nombres, métodos y cuerpos se explican solos. * Cada fila de la tabla de fallos remite sin ambigüedad a una situación concreta de negocio del paso 05. * El de al lado puede diseñar directamente desde tu tabla el controlador del paso 10 sin preguntarte nada: esa es la prueba del contrato. ===== 5. Pendientes ===== * La implementación del contrato, en **Spring Boot** (**10**): DispatcherServlet, controladores anotados y manejo global de excepciones.