Hexagonal architecture: principles, ports and adapters, benefits
Ports, adapters and domain isolation: the principles of hexagonal architecture, its synergy with DDD and its concrete benefits in testability over time.
ADSERVIO INSIGHTS · DEVSECOPS

KEY POINTS
- Hexagonal architecture, formalised by Alistair Cockburn as "ports and adapters", places business logic at the centre and pushes all infrastructure to the edge.
- The guiding principle is dependency inversion: the domain depends on nothing, everything depends on the domain, database, web framework and external services become interchangeable.
- Primary ports expose the use cases (REST, GraphQL, gRPC, events); secondary ports abstract persistence, message brokers and third-party APIs, including LLM providers.
- Combined with Domain-Driven Design, it structures modular monoliths and prepares a possible extraction into microservices without a big bang.
- Its measurable benefits: fast unit tests with no infrastructure, changes isolated inside adapters, lasting maintainability and reduced vendor lock-in.
SECTION 1
Hexagonal architecture: definition and origins of ports and adapters
Hexagonal architecture is a design model that places business logic at the centre of the application and pushes all inputs and outputs, user interfaces, databases, external services, to the edge. Formalised by Alistair Cockburn in 2005 under the name "ports and adapters", it addresses a problem every team knows: applications where business logic leaks into controllers, where SQL queries contaminate the domain, and where every change becomes risky because everything depends on everything.
Twenty years later, the pattern has lost none of its relevance, it has gained some. The multiplication of entry channels (REST APIs, GraphQL, gRPC, event streams, conversational interfaces), the volatility of cloud infrastructure choices and the arrival of AI coding assistants reinforce the need for explicit boundaries between what belongs to the business and what belongs to the technology. In 2026, hexagonal architecture serves as the reference foundation for modular monoliths as much as for well-designed microservices.
Its fundamental principle fits in one sentence: the domain depends on nothing, everything depends on the domain. Business rules are unaware of the web framework, the database or the messaging provider. This dependency inversion, aligned with clean architecture principles, makes it possible to replace any technical component without touching the application core.
SECTION 2
Ports and adapters: the layered structure of the application core
The hexagon is organised into three concentric zones with strictly delimited responsibilities, and a dependency rule that always points towards the centre.
### The domain core, home of the business rules
At the centre live the entities, value objects and domain services that carry the business invariants: computing a price, validating an order, orchestrating a use case. This code is written in the language of the business, with no framework annotation and no technical import. It is the most valuable and most durable part of the application, the one that outlives technology changes.
### Ports, interfaces that define the boundaries
Ports are interfaces declared by the domain itself. A primary port describes what the application can do (create an account, place an order); a secondary port describes what it needs (persist an entity, publish an event, notify a customer). The domain defines the contract, never the implementation.
### Adapters, translators between two worlds
Adapters implement the ports and handle the translation between the outside world and the application core: an HTTP controller converts a JSON request into a use-case call, a repository translates an entity into database rows. Each adapter is replaceable independently of the others, which turns the boundary into a genuine decoupling point.
@cite:decouplage-par-conception-construire-des-bibliotheques
SECTION 3
Primary side and secondary side: the two faces of the hexagon
The model distinguishes two operational sides. The primary, or "driving",side gathers everything that drives the application: REST or GraphQL APIs, gRPC endpoints, Kafka consumers, scheduled jobs, command-line interfaces, and now AI agents that invoke use cases through tooling protocols such as MCP. All of them go through the same primary ports: adding an entry channel means writing an adapter, never modifying the domain.
The secondary, or "driven",side gathers everything the application drives: relational or document databases, message brokers, caches, file systems, partner APIs. Here again, the domain only knows the interfaces; the assembly configuration injects the concrete implementations at startup.
This symmetrical organisation has a major practical consequence: entry points and storage mechanisms evolve independently. Migrating from one managed database to another, exposing an existing use case asynchronously or plugging in a new client channel are projects confined to the edge, plannable without freezing business development.
A concrete example makes the flow readable: an order arrives through the REST adapter, which converts it into a call to the "place an order" primary port; the use case applies the domain rules, stock check, amount calculation, condition validation, then calls the secondary ports to persist the order and publish an event; the corresponding adapters translate those calls to the database and the message broker. Neither the controller nor the repository contains a single business rule: they do nothing but translate.
SECTION 4
Hexagonal architecture and Domain-Driven Design: a natural synergy
Hexagonal architecture says where to place the technical boundaries; Domain-Driven Design says how to carve up the business. The two approaches complement each other: each DDD bounded context becomes an autonomous hexagon, with its own model, its own ports and its own ubiquitous language. The DDD anti-corruption layer finds its natural implementation home in the adapters.
This combination is the foundation of the modular monolith, the recommended starting architecture in 2026 for the majority of new products: a single deployment, but isolated business modules that communicate through explicit interfaces or internal events. Tools such as Spring Modulith on the Java side or Nx workspaces on the TypeScript side verify these boundaries at build time and prevent wild dependencies between modules.
The day a module genuinely needs to scale independently, extracting it into a microservice comes at minimal cost: the ports already exist, and internal calls simply become network calls. Conversely, an unstructured monolith condemns you to a rewrite. The hexagon is thus the best insurance against big-bang migrations.
@cite:domain-driven-design-principes-benefices
SECTION 5
Testability and maintainability: the measurable benefits
The most immediate benefit of hexagonal architecture is testability. Since the domain depends on no infrastructure, its rules are tested in memory, without a container, without a database, without complex mocks: thousands of unit tests run in a few seconds, which makes TDD genuinely practicable day to day.
### A test pyramid that is finally balanced
Adapters, for their part, are verified through targeted integration tests, with Testcontainers for persistence, consumer-driven contracts for APIs, while a handful of end-to-end tests validate the assembly. Each test category has a clear scope, which eliminates the slow, brittle suites that mix everything together.
### Changes confined to the edge
Maintainability flows from the same property: a database schema change, a framework upgrade or the replacement of a third-party service stays confined to the adapter concerned. Teams that adopt this structure see a lasting drop in the cost of change, because the code surface touched by each technical change shrinks drastically. Compared with a classic layered architecture, where the business layer often depends on the persistence layer, dependency inversion makes components genuinely interchangeable rather than theoretically separated.
Beware of the classic traps, however: ports that mirror the API of a particular technology, an interface exposing SQL queries abstracts nothing, an anemic domain where all the logic leaks into the adapters, or a proliferation of interfaces with no added value. A port is designed from the point of view of the business need, never of the tool that implements it: that is what guarantees the abstraction will hold the day the tool changes.
SECTION 6
The hexagon in the era of generative AI and multi-provider systems
The rise of generative AI gives the pattern renewed relevance. Integrating a language model means depending on an external API whose pricing, capabilities and models change every quarter. Placing that dependency behind a secondary port, a "generate a response" or "classify a document" contract, makes it possible to switch providers, route between several models or fall back to self-hosted inference without rewriting a single business rule. LLM gateways and orchestration frameworks slot in naturally as adapters.
The boundary also works in the other direction: AI coding assistants produce markedly safer code in a hexagonal codebase, because the explicit conventions, named ports, isolated adapters, dependency-free domain, give them a verifiable frame. An architecture with clean boundaries is easier to explain to an agent than a plate of spaghetti, and the fast domain tests immediately validate its proposals.
Finally, the hexagon protects against cloud vendor lock-in: message queues, object storage and managed services remain implementation details behind ports, which keeps open the reversibility options demanded by European regulators and procurement departments.
@cite:decisions-architecturales-logicielles-qui-doit-etre-implique
SECTION 7
Adopting hexagonal architecture without over-engineering
Hexagonal architecture is not free: it adds interfaces, transfer objects and team discipline. On a simple CRUD application with no business logic, it amounts to over-engineering; on a rule-rich system meant to last and to change technologies, it pays for itself within the first months. The right criterion is the density of business logic and the life expectancy of the product, not architectural fashion.
Successful adoption relies on pragmatism: start by isolating the domain from the framework, introduce ports on the most volatile dependencies, persistence, third-party services, AI providers, then tool the boundaries with dependency rules verified in continuous integration, via ArchUnit or dependency-cruiser, so the architecture withstands time and newcomers.
The team's ramp-up matters as much as the technique: naming the ports in the language of the business, documenting the dependency rule and checking the boundaries during code review are all part of the same investment. Teams that succeed treat the architecture as a living product, with decisions traced in ADRs rather than in the memory of a few developers.
At Adservio, our architects support the design and implementation of pragmatic hexagonal architectures: domain mapping, bounded context definition, test strategy and boundary governance. The goal is never dogmatic compliance with a diagram, but systems that are testable, scalable and maintainable over the long term, able to absorb the next technology waves without a rewrite.
FAQ
Frequently asked questions
What is hexagonal architecture?
It is a design model, formalised by Alistair Cockburn as "ports and adapters", that places business logic at the centre of the application and pushes all inputs and outputs to the edge. The domain depends on no infrastructure: database, web framework and external services become interchangeable details.
What is the difference between a port and an adapter?
A port is an interface declared by the domain: it describes what the application can do (primary port) or what it needs (secondary port). An adapter implements that contract and handles the translation with the outside world, HTTP controller, persistence repository, third-party API client.
How does hexagonal architecture improve testability?
The domain is tested in memory, without a database or container: thousands of unit tests run in a few seconds. Adapters are verified through targeted integration tests, for instance with Testcontainers, which produces a fast, reliable test pyramid.
Are hexagonal architecture and DDD the same thing?
No, but they complement each other: Domain-Driven Design carves the business into bounded contexts, and hexagonal architecture materialises the technical boundaries of each context. Combined, they form the foundation of the modular monolith and prepare a microservices extraction without a big bang.
Should you always use hexagonal architecture?
No. On a simple CRUD application with no business logic, it adds unnecessary complexity. It is justified as soon as the system is rich in business rules, meant to last and exposed to technology changes, including the replacement of LLM providers or cloud services.
ABOUT ADSERVIO
Adservio is an AI-native digital transformation partner: AI-augmented IT departments, software engineering, DevOps, MLOps, cybersecurity and AI governance.
Let's talk about your project: hello@adservio.fr · adservio.fr/contact