Overview
Hexagonal architecture (also called ports and adapters) organizes code so that business logic sits at the center, isolated from external concerns like databases, UIs, and third-party services. The core domain exposes “ports” — interfaces defining what it needs — and “adapters” implement these interfaces for specific technologies. This inversion means the domain never imports infrastructure code, making it testable in isolation and portable across different delivery mechanisms. Coined by Alistair Cockburn, this pattern directly addresses the problem of business logic becoming entangled with framework and persistence concerns.
Key Concepts
- Ports — Interfaces defined by the domain. Driving ports (inbound) handle commands from the outside; driven ports (outbound) define what the domain needs from infrastructure.
- Adapters — Concrete implementations that connect ports to real technologies (REST controller, PostgreSQL repository, RabbitMQ publisher).
- Domain core — Pure business logic with no framework dependencies. Contains entities, value objects, and domain services.
- Dependency rule — Dependencies point inward. Adapters depend on ports; the domain depends on nothing external.
- Testability — The domain can be tested with in-memory adapters, eliminating the need for databases or HTTP servers in unit tests.
Trade-offs
- More files and interfaces than a simpler layered architecture
- Can feel over-engineered for small CRUD applications
- Requires discipline to maintain the dependency rule as the codebase grows
- Team must understand the pattern to contribute effectively
Related
- Dependency Injection is the mechanism that wires adapters to ports
- SOLID Principles — hexagonal architecture is a direct application of Dependency Inversion
- Separation of Concerns is the foundational principle behind this pattern