06 - Módulos: pedidos y API pública

Hasta aquí la tienda era un solo bloque por capas. Este hito aplica el tema 04 — Monolito modular: se añade el segundo problema de negocio, pedidos, y con él la organización en módulos — cada uno protege su interior y expone una API pública. Los pedidos reservan el stock del catálogo por esa API: la primera colaboración síncrona entre módulos de la práctica.

Pieza Cambio en este hito
Contrato v0.2.0: las operaciones de pedidos
Estructura Paquetes catalog y orders como módulos; API pública del catálogo
Verificación Límites entre módulos con Spring Modulith; capas internas con ArchUnit
  1. Añadir a openapi.yaml (v0.2.0) las operaciones de pedidos y regenerar:
Operación Petición Respuestas
Crear pedido POST /api/orders · OrderRequest 201 · 400 · 404 · 409
Ficha de pedido GET /api/orders/{id} 200 · 404
Cancelar POST /api/orders/{id}/cancel 200 · 404 · 409
  1. Esquemas nuevos: OrderRequest (userId y líneas), OrderLineRequest (productId, quantity), OrderLine (productId, quantity, unitPrice) y Order (id, userId, state, lines, total).
  2. El 409 ya entró en el contrato en el hito 04 con las reglas de estado del catálogo; aquí se repite el patrón con el stock insuficiente, el primer error de estado del negocio de pedidos. El 400 de formato existe desde el hito 05.
El campo userId de OrderRequest es provisional: no hay usuarios todavía y el comprador se indica en el cuerpo. En el hito 08 la identidad vendrá del token y el campo desaparecerá del contrato.
  1. Reorganizar los paquetes por módulo de negocio (con git mv, para conservar el historial): el catálogo queda dentro de shop.catalog; el pedido nace directamente en shop.orders; la raíz de composición — ShopApplication y la configuración de arranque — queda en el paquete base.
  2. API pública del catálogo: la interfaz CatalogApi del esquema de la especificación, expuesta en catalog.api. Por ella cruzan al pedido las capacidades que necesita — reservar las unidades de una línea, dejando capturado el precio del momento, y liberar las reservadas al cancelar —, con sus datos y sus errores. La forma exacta de esa API — firmas, datos, qué excepciones cruzan el límite — es diseño de cada quien; lo fijo es el resultado: si una línea falla, el stock queda como estaba y no se crea nada.
  3. El interior de cada módulo queda protegido; lo único que el pedido puede consumir del catálogo es su API pública. Lo que cruza el límite forma parte del contrato público del módulo del catálogo; las excepciones de su dominio interno no salen de él (sección 4).
  4. El interior de orders lo compone cada quien con las piezas del tema 04 — REST propio, casos de uso, servicio y persistencia JDBC —. Las tablas orders y order_lines de la especificación entran en el init.sql (reiniciar el volumen de MariaDB para recargar la semilla); el precio de cada línea se guarda capturado (unit_price de la especificación).
  • Al crear el pedido, todas las líneas reservan su stock por la API pública del catálogo; el pedido y sus líneas se guardan con los precios capturados.
  • Todavía sin transacciones: sostener la garantía del contrato — si una línea falla, el stock queda como estaba y no se crea el pedido — con JDBC suelto obliga a componer la protección a mano, y el resultado es frágil: si persistir el pedido falla después de reservar, el stock queda reservado sin pedido. Es el punto que el hito 07 resolverá con transacciones; el fallo servirá de pista para valorarlas.
  • Cancelar solo cabe desde CREATED; cancelar un pedido ya cancelado es un estado imposible del dominio de pedidos, que responde 409. También se mapean los errores del catálogo que llegan al pedido: 404 para producto desconocido, 409 para stock insuficiente.

La verificación de módulos pasa a correr con cada build, según el tema 04: los límites entre módulos con Spring Modulith y las reglas de capas dentro de cada módulo con ArchUnit. Opcional: generar la documentación de módulos con el Documenter del tema.

  • Módulo orders (aislado, con la API pública del catálogo doblada): crear un pedido reserva el stock de todas las líneas y persiste el pedido; si una línea falla, no queda nada; cancelar libera el stock y pasa el estado a CANCELLED; cancelar dos veces falla.
  • Módulo catalog (aislado): la reserva y la liberación por la API pública mantienen el stock coherente.
  • Presentación de pedidos (con los módulos doblados): estados 201 / 200 / 404 / 409 según contrato.
  • Lo de los hitos anteriores sigue verde: catálogos y productos no cambian de comportamiento con la reorganización.
  • La verificación de módulos y las reglas de capas pasan en cada build.
  • Los pedidos funcionan de punta a punta: crear, consultar y cancelar desde Swagger UI, con el stock reservado y liberado de verdad.
  • Un pedido con una línea sin stock responde 409 y no deja nada reservado.
  • orders solo consume la API pública del catálogo: lo comprueba la verificación, no la buena voluntad.
  • Contrato en v0.2.0; commit y tag hito-06.

Siguiente hito: hito 07 — Persistencia con JPA.

  • clase/daw/dws/1eval/practicas/p6.txt
  • Última modificación: 2026/10/28 13:32
  • por cesguiro