Hexagonal architecture
Hexagonal architecture protects specialist logic behind self-defined ports. Adapters translate between these contracts and concrete technologies.
- PortTechnically designated contract defined by the core.
- Incoming and outgoingIncoming adapters call the core, outgoing ones call it.
- TestabilityTest adapters replace any infrastructure.
Context
Why this is important
The specialist core remains free of technology, the adapters can be exchanged. The benefit lies mainly in the testability and in several approaches to the same core. Dependency inversion explains why arrows point inward, the ACL, which translates at the border; this is about the overall form.
This building block explains ports and adapters around a specialist core. For the general dependency direction, see Dependency Inversion.
At a glance · Core in a hexagon with ports
Swap adapter, core remains
The internal payment module of the modular monolith decides on payment states. A provider adapter translates its port into the external API.
This is how you read the picture
- Port The apricot chips “Commit payment”, “charge provider” and “save payment” on the hexagon.
- Incoming and outgoing On the left the incoming port with its adapters, on the right the two outgoing ports.
- Testability If all test adapters are selected, the badge appears and the core remains unchanged.
in-depth (driving, primary)Request for payment
Outgoing (driven, secondary)Providers burdened
Outgoing (driven, secondary)Save payment
Changes to the technical core: 0
Operational case: All ports are connected to real adapters, the core works unchanged.
Benefits & limitations
Helps if:
- Ports keep the core independent of adapters, so that business rules remain auditable without infrastructure.
- A common application contract connects several input or output paths, while adapters translate their protocols.
- A business port encapsulates technical formats and errors and keeps providers interchangeable.
Boundaries
- Test doubles do not replace a real provider: serialisation and failure behaviour still need integration tests.
- Port inflation: A port for every little thing costs more than it protects.
- Technical types in the port further tie the core to the infrastructure.
In practice
- Express ports as business capabilities and describe expected results and failures. Keep library and storage types in adapters so the core remains independent.
- Keep adapters responsible for translation and technical communication. Check that the same core fulfils the same business contract through different inbound or outbound adapters.
- Test the core and real adapters at their respective boundaries. Dependency Inversion examines dependency direction; Module Boundaries clarifies business ownership.
Read the detailed explanation
A port describes an application input or output in business terms. Adapters translate between this contract and technical protocols or storage. The application core defines the capabilities it needs; adapters connect concrete libraries, databases and transports.
Inbound adapters start use cases; outbound adapters fulfil their dependencies. The separation supports testing and replacement when a port represents a meaningful boundary. Infrastructure types in a port merely move coupling into an interface.
Dependency Inversion explains how the core defines required capabilities; Module Boundaries shows where these contracts connect business responsibilities.
Related approaches include Clean Architecture and Onion Architecture. They share the central idea: dependencies point inwards, and the business core remains independent of infrastructure details.
Check your understanding
Test yourself in three stages
ReadingCheck in the picture
You choose “Test-Double” and “In-Memory”, but leave “Web-Checkout”. What does the picture show, and what counts “changes at the specialist core”?
View the solution with justification
A mixed constellation. The counter remains at 0Because only adapters have been changed.
ApplyingTransferred to a new situation
A nightly matching job is to re-commission open payments. What do you add?
View the solution with justification
Another incoming adapter, the job, for the port “Assign payment”. The core and port remain unchanged.
EvaluateWeighing an alternative
The team only tests with test double and in-memory. Is that enough?
View the solution with justification
Advantage: fast, stable tests of the business rules. Disadvantage: serialization, error behavior of the provider and database behavior remain unchecked. Recommendation: Maintain specialist tests with doubles and supplementary few integration tests against real providers and real database.
Explore further
These building blocks continue the thoughts of this page.
References
- Alistair Cockburn - Hexagonal Architecture (opens in new tab)Original description of ports, adapters and interchangeable external connections.
- Microsoft · Common Web Application Architectures (opens in new tab)Compares layers and clean architecture including dependency direction.
- Microsoft Architectural Principles (opens in new tab)Explains Separation of Concerns, Encapsulation and Dependency Inversion.