Modular monolith with Quarkus - Supporting Hexagonal Architecture #51183
doogle-oss
started this conversation in
Community
Replies: 2 comments 4 replies
-
|
I did not know mermaid makes things so easy to explain 🥇 |
Beta Was this translation helpful? Give feedback.
0 replies
-
|
Thanks for sharing! Very interesting! Do you have concrete code we can look at? |
Beta Was this translation helpful? Give feedback.
4 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Over past 2 years spring team had been focussing on spring modulith project to provide a clear flow on how hexagonal architecture based applications can be built easily.
Is there some tutorial or details on the same to do in Quarkus.
I have come up with the following but i feel there is a need, may be a quarkus insights for this to clarify the right flow.
✔ Each module = one bounded context
✔ Modules do NOT call each other via direct Java dependency
✔ Modules communicate via CDI Events or Messaging (Kafka)
Option A — CDI Domain Events (recommended for monolith)
📌 Works exactly like Spring Modulith’s Domain Events.
Publish (order-module)
🔁 2. Module Communication Patterns (Internal)
Listen (notification-module)
Benefits
✔ Zero coupling
✔ Fully synchronous or async
✔ Easy to test
✔ Similar to Modulith EventRegistry
🧩 3. Module Structure Template (Example: order-module)
Only api package is public
Everything under internal is private to module (enforced via ArchUnit).
📦 4. Main Application (app-shell)
app-shell is the only module exposing REST endpoints.
Example:
Key rule:
➡️ REST controllers never exist inside individual modules
➡️ Only the shell exposes APIs
🧪 5. Enforcing Module Boundaries with ArchUnit
To simulate Spring Modulith’s boundary checks, add:
architecture-tests/src/test/java/ModuleBoundaryTest.java
You can extend this for all modules.
🌐 6. External Communication (Kafka, REST, S3, etc.)
Use Kafka only for external cross-service events when needed.
Example Quarkus Kafka Listener:
⚡ 7. Quarkus Dev Productivity Advantages
Dev Mode (mvn quarkus:dev) → live reload modules
Native Build → faster than Spring Modulith if deployed as monolith
DevServices → automatic Postgres, Kafka, Redis containers per module
Quarkus Dev UI → visualize components and configs
flowchart TB subgraph APP_SHELL["🟦 App Shell (Quarkus Application)"] API["REST Controllers\nHTTP Entry Points"] CONFIG["Configuration / Security Filters"] end API --> ORDER_API API --> USER_API API --> INVENTORY_API API --> PAYMENT_API API --> NOTIF_API %% ORDER MODULE subgraph ORDER["🟩 Order Module"] ORDER_API["Order API\n(Public Interface)"] ORDER_INTERNAL["Order Internal\nDomain/Service/Repo"] ORDER_EVENTS["Order Events"] end %% USER MODULE subgraph USER["🟩 User Module"] USER_API["User API"] USER_INTERNAL["User Internal"] end %% INVENTORY MODULE subgraph INVENTORY["🟩 Inventory Module"] INVENTORY_API["Inventory API"] INVENTORY_INTERNAL["Inventory Internal"] end %% PAYMENT MODULE subgraph PAYMENT["🟩 Payment Module"] PAYMENT_API["Payment API"] PAYMENT_INTERNAL["Payment Internal"] end %% NOTIFICATION MODULE subgraph NOTIF["🟩 Notification Module"] NOTIF_API["Notification API"] NOTIF_INTERNAL["Notification Internal"] end %% CDI EVENTS ORDER_INTERNAL --> CDI_EVENT["🔄 CDI Event Bus"] PAYMENT_INTERNAL --> CDI_EVENT CDI_EVENT --> NOTIF_INTERNAL CDI_EVENT --> INVENTORY_INTERNAL CDI_EVENT --> PAYMENT_INTERNAL %% DATABASES ORDER_INTERNAL --> POSTGRES[(PostgreSQL)] USER_INTERNAL --> POSTGRES INVENTORY_INTERNAL --> POSTGRES PAYMENT_INTERNAL --> POSTGRES %% REDIS INVENTORY_INTERNAL --> REDIS[(Redis Cache)] %% KAFKA (Optional External Integration) PAYMENT_INTERNAL --> KAFKA[(Kafka Broker)] NOTIF_INTERNAL --> KAFKA %% STYLES style APP_SHELL fill:#dbeafe,stroke:#1e40af style ORDER fill:#dcfce7,stroke:#166534 style USER fill:#dcfce7,stroke:#166534 style INVENTORY fill:#dcfce7,stroke:#166534 style PAYMENT fill:#dcfce7,stroke:#166534 style NOTIF fill:#dcfce7,stroke:#166534 style CDI_EVENT fill:#fff7ed,stroke:#b45309 style POSTGRES fill:#e9d5ff,stroke:#6b21a8 style REDIS fill:#fecaca,stroke:#b91c1c style KAFKA fill:#fef9c3,stroke:#ca8a04Beta Was this translation helpful? Give feedback.
All reactions