Hexagonal architecture diagrams

Ports and adapters, drawn as the shape the pattern is named after.

Hexagonal architecture, or ports and adapters, puts domain logic at the centre and pushes every external dependency to an adapter at the edge. The diagram is worth drawing because the pattern's whole claim is about which direction dependencies point, and that is exactly what prose obscures.

When to use these

When not to

Common mistakes

The usual failure is an adapter that has leaked domain logic into it, or a port defined in terms of the technology behind it rather than what the domain needs. If your port is called `UserRepository` and has a `findBySqlQuery` method, the dependency is pointing the wrong way.

The 3 templates

Hexagonal Service.puml

One service, its ports and its adapters.

Hexagonal Service: rendered example
Show the source
@starthex
Title("Order Service")
Domain("Domain")
Module("Order · LineItem")
Module("Place / Cancel")
Driving("Consumer", "REST API")
Driven("Order Repo", "PostgreSQL")
@endhex

Notes and a copy button for this template

Hexagonal Application (concentric).puml

Concentric view: domain, application, infrastructure.

Hexagonal Application (concentric): rendered example
Show the source
@starthex
Title("Commerce Platform")
Domain("Domain")
Module("Orders")
Module("Inventory")
Module("Payments")
Module("Shipping")
Driving("Web App", "REST API")
Driving("Mobile App", "REST API")
Driving("Ops Console", "Admin UI")
Driven("Payment adapter", "Card Processor")
Driven("Email adapter", "Email Provider")
Driven("Repository", "SQL Database")
@endhex

Notes and a copy button for this template

Multi-domain (integration).puml

Several hexagons and the contracts between them.

Multi-domain (integration): rendered example
Show the source
@starthex
Channel("order.placed")

Service(orders, "Order Service") {
  Domain("Ordering")
  Module("Cart")
  Module("Checkout")
  Driving("Consumer", "REST API")
  Publish("order.placed", "Event Publisher")
}

Service(shipping, "Shipping Service") {
  Domain("Shipping")
  Module("Dispatch")
  Module("Tracking")
  Consume("order.placed", "Event Handler")
  Driven("Repository", "SQL Database")
}
@endhex

Notes and a copy button for this template

Render these offline

Every template here ships in Gnomon and renders on your machine, with no account and no diagram uploads. The browser editor is free and needs no install.

Get GnomonOpen the browser editor

Analytics cookies (optional)

May we use Google Analytics to understand visits, product links and feature use? If you accept, Google receives usage and device information, including your IP address, and sets analytics cookies. We do not send your documents, filenames or account details. Advertising features are disabled.

Analytics is off until you accept. Your choice is saved on this browser for 180 days using necessary local storage. You can change it at any time in Analytics preferences. Closing this message rejects analytics. Read our privacy policy.