En el hito de partida la aplicación se construyó primero en código y el contrato quedó implícito: nadie ajeno al código podía conocer GET /api/products sin leer su implementación. Este hito aplica el tema 02 — API First: toda la API del módulo de catálogo — ahora con catálogos y con la paginación que el listado plano ya necesita — se diseña y se revisa antes de implementarla, y el contrato — un documento OpenAPI — pasa a ser la fuente de verdad.
| Pieza | Cambio en este hito |
|---|---|
| Contrato | Nace openapi.yaml (v0.1.0): catálogos, productos, listado paginado y reglas 409 |
controller | El listado plano de la partida desaparece; las operaciones nuevas se implementan desde el contrato |
| Herramientas | El esqueleto se genera con openapi-generator; Swagger UI (springdoc) lo hace navegable y ejecutable |
openapi.yaml con la API completa del módulo de catálogo:| Operación | Petición | Respuestas |
|---|---|---|
| Listado de catálogos | GET /api/catalogs | 200 · Catalog[] |
| Ficha de catálogo | GET /api/catalogs/{id} | 200 · 404 |
| Alta de catálogo | POST /api/catalogs | 201 |
| Modificación de catálogo | PUT /api/catalogs/{id} | 200 · 404 |
| Borrado de catálogo | DELETE /api/catalogs/{id} | 204 · 404 · 409 |
| Productos de un catálogo | GET /api/catalogs/{id}/products?page&size | 200 · 404 |
| Ficha de producto | GET /api/products/{id} | 200 · 404 |
| Alta de producto | POST /api/products | 201 · 404 |
| Modificación de producto | PUT /api/products/{id} | 200 · 404 |
| Borrado de producto | DELETE /api/products/{id} | 204 · 404 |
Catalog y CatalogRequest; Product (respuesta, con id y catalogId) y ProductRequest (con catalogId, sin id); ProductPage para el listado paginado del catálogo — content más los metadatos page, size, totalElements y totalPages; y Problem (RFC 9457: type, title, status, detail) para los errores. Los 404 de catálogo o producto inexistente y los 409 de estado — nombre de catálogo repetido, catálogo con productos — se declaran también en el contrato.page (desde 0, por defecto 0) y size (por defecto 10) como parámetros de GET /api/catalogs/{id}/products; la respuesta lleva siempre los metadatos.src/main/resources/openapi.yaml, se versiona en el repositorio y su info.version sube en cada hito que toque la API.GET /api/catalogs/{id}/products. Es la primera decisión que el contrato toma sobre el código.
mvn compile tras cada cambio del openapi.yaml: el esqueleto resultante es la guía de lo que queda por implementar.SQL de inserción, modificación o borrado en la persistencia JDBC; el mecanismo sigue siendo el de 1.º DAW.page, size, totalElements, totalPages) se resuelven con JDBC a mano — sin Spring Data, que llega con el hito 07. El contrato exige la respuesta completa con sus metadatos en cada listado.catalogId apunta a un catálogo que no existe; 409 si el nombre del catálogo se repite al crear o modificar, y si se intenta borrar un catálogo con productos (la comprobación, antes del borrado)./v3/api-docs y la UI ejecutable en /swagger-ui.html, para revisar y probar cada operación.Periféricos (12 productos) reparte en 2 páginas con size 10.openapi.yaml está en el repositorio con info.version 0.1.0.hito-04.openapi.yaml y se regenera. Los hitos que no tocan la API no lo tocan.
Siguiente hito: hito 05 — Validación e invariancias.