Tabla de Contenidos

04 - API First: el contrato antes del código

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

1. Diseñar el documento

  1. Redactar 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
  1. Esquemas: 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.
  2. La paginación se define 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.
  3. Aún sin constraints de validación: llegan en el hito 05; la especificación de este hito describe las operaciones y sus errores de estado, no el formato de los datos.
  4. Esta primera versión se redacta y se revisa antes de generar código: es el momento de acordar el contrato.
  5. El documento se guarda en src/main/resources/openapi.yaml, se versiona en el repositorio y su info.version sube en cada hito que toque la API.
El listado plano de la partida desaparece: veintiocho productos en una sola respuesta no escala y no deja navegar por catálogos. El contrato lo sustituye por el subrecurso paginado GET /api/catalogs/{id}/products. Es la primera decisión que el contrato toma sobre el código.

2. Generar desde el contrato

3. Implementar desde el contrato

4. Swagger UI

Comprobación

A partir de ahora el contrato manda: todo cambio de la API se escribe primero en openapi.yaml y se regenera. Los hitos que no tocan la API no lo tocan.

Siguiente hito: hito 05 — Validación e invariancias.