Overview
You have finished the by-example tracks for both DDD and Hexagonal Architecture. You know what an aggregate is. You know what a port is. Now the question is: how do they wire together in a real production codebase that ships? This section answers that question through two parallel tracks against the same shared Procure-to-Pay domain — so the only thing that changes between tracks is the language and framework.
What's in this section
Two production-wiring tracks, both running against the hypothetical procurement-platform-be service (Purchase Requisitions → POs → Goods Receipt → Three-Way Matching → Payment):
- DDD + Hexagonal in Practice — F# in the Field — F# / Giraffe / Npgsql, 27 guides
- DDD + Hexagonal in Practice — Java in the Field — Java 25 / Spring Boot 4, 27 guides
Both tracks share the same 27-guide numbering (beginner 1–6/7, intermediate 8–14/15, advanced 15/16–22, production 23–27) so cross-track comparison is trivial: Guide 5's F# port definition versus Guide 5's Java interface definition is a single side-by-side read.
Prerequisites
Complete the by-example tracks before starting either in-the-field track:
The in-the-field tracks use terms like aggregate, port, adapter, bounded context, and repository pattern without redefinition. If any feel unfamiliar, finish the prerequisite track first.
Running domain — Procure-to-Pay procurement platform
Both tracks reason against the same hypothetical service: procurement-platform-be, the backend of a Procure-to-Pay (P2P) procurement platform.
| Bounded context | Aggregate root | Responsibility |
|---|---|---|
purchasing | PurchaseRequisition, PurchaseOrder | Requisition lifecycle, approval routing, PO issuance |
supplier | Supplier | Vendor master, approval state, risk score |
receiving | GoodsReceiptNote | Goods receipt against PO, quantity verification |
invoicing | Invoice | Invoice registration, three-way matching (PO ↔ GRN ↔ Invoice) |
payments | Payment | Payment run scheduling, bank disbursement |
murabaha-finance | MurabahaContract (optional Sharia tier) | Bank-purchased asset, markup contract, repayment schedule |
Same contexts, same aggregates, same domain events, same ports across both tracks — only the language and framework idioms differ.
Why two parallel tracks
Comparing the F# wiring of Guide 5 (a port as a function type alias) against the Java wiring of Guide 5 (a port as an interface) against the same business problem is the fastest way to internalise the structural decisions that hexagonal architecture and DDD demand — regardless of which paradigm you ultimately ship with.
Last updated May 16, 2026