Hexagonal architecture - Another way to the hexagone
The content here is under the Attribution 4.0 International (CC BY 4.0) license
Theory
Hexagonal Architecture, also known as the Ports and Adapters pattern, offers a powerful way to design software systems that are modular, testable, and adaptable to change. This architectural style emphasizes the separation of concerns, ensuring that core business logic remains independent of external systems such as databases, user interfaces, or third-party services.
In this blog post, we’ll explore Hexagonal Architecture in two parts. The first part dives into the theory, explaining its principles, benefits, and how it contrasts with traditional layered architectures. The second part brings these concepts to life with a real-world implementation based on my interpretation of Hexagonal Architecture, demonstrating how to structure code for flexibility and maintainability.
Hexagonal
I got to know hex architecture(I am going to follow this pattern from now on to refer to the hexagonal architecture) in the clean architecture book, indeed it was inspired by Uncle Bob to get the clean architecture in place. Alistair Cockburn realized that there was a different approach to building applications instead of the classical layered architecture:
The attempted solution, repeated in many organizations, is to create a new layer in the architecture, with the promise that this time, really and truly, no business logic will be put into the new layer.
A more flexible way of dealing with different adapters in the application and using the same code to process business rules. Even though experts argue that there are differences between open and closed layers, to avoid such interactions or constraint violations, in the hex architecture the approach is different stating that the goal is to avoid it by design instead of trying to enforce a constraint. Nevertheless, Stenber in his blog written for infoQ says that hexagonal architecture is an example of a layered architecture as it conforms to all the constraints and properties of a layered architecture (Stenber, 2014).
Hexagonal vs Clean Architecture?
Hexagonal architecture is usually mixed with clean architecture, even though, it was used as an inspiration for the clean architecture, they are different. Valentina Cupác describes that in her talk with details.
In my observations throughout code bases, both are often mixed together. However, Clean Architecture is more prescriptive than Hexagonal Architecture. For example, Juan Manuel Garrido de Paz describes that “Ports & Adapters pattern says nothing about the structure of the inside of the hexagon.” Ports & Adapters is another way to name the same architectural style.
Which goes against the opinion from Juan Manuel, who says that the “pattern” says nothing about layers. However, what I see lacking in his argument is: what is a layer anyway? Such an abstract definition as an architectural style may be interpreted differently by different people, which leads to those different opinions. The naming “layer” might be too abstract, leading to confusion when communicating the same idea.
Another way to the hexagone
Alistair in the “hexagone” - YouTube playlist DDD - FR elaborates on his insights when developing and formalizing the architectural style that is widely known today by developers. For curious people, this is a video that explains the why’s behind the naming, the decision and the need from Alistair to create the style.
Definition
Let’s start with the diagram from the architectural style creator Alistair Cockburn that has this image in his blog post:

Hexagonal architecture is defined in different aspects. These aspects are something that was created to define this architectural style, and I believe they are the key:
- ports, as the author describes “The term “port and adapters” picks up the ‘’purposes’’ of the parts of the drawing. A port identifies a purposeful conversation”.
- adapters, you might have many adapters for a single port.
In the book Strategic Monoliths and Microservices (Vaughn Vernon, 2021) Vaughn Vernon and Tomasz Jaskula also used a similar definition, on the other hand, what caught my attention to their definition is the way used to differentiate the layered architecture from hexagonal.
Ports and Adapters are the one of the aspects of this architectural style that deserves attention. A driver adapter implements a driver port interface, translating requests from a specific technology into a technology-agnostic format that the driver port can understand and process.
Paz uses the naming “Driver” to refer to the interface that will control how to interact with the application and “Driven” to refer to the interface that will act as an output boundary.
A note on the implementation
In my implementation that is referenced later in this post, I used the naming “inbound” and “outbound” to refer to the interfaces that are used to interact with the application. The inbound is the interface that is used to interact with the application, while the outbound is the interface that is used to interact with the external systems:
- inbound: Driver
- outbound: Driven
In that sense, the driver can be a CLI, a GUI, or even a REST API, while the driven can be a database, a message broker, or any external system that the application interacts with.
What are the disadvantages of hexagonal architecture?
At first, the hexagonal architecture seems to be a magical approach that will automagically give testability to any application, at least this is what some of the articles on the web sells the hexagonal architecture. Nevertheless, some of the implications that come when adopting hexagonal architecture are:
- The developer experience: as the implementation of hexagonal architecture depends on interpretation, it varies based on the programming language and the years of experience of the developer writing the code. Hexagonal architecture usually is not the first style that one starts with. It is MVC that comes embedded in different frameworks.
- The understanding of the developer on the libraries and the frameworks being used: the different ecosystems of different programming languages bring challenges as they offer a pre-created structure of how the problem should be solved. Understanding each piece of them is key to creating abstraction to create the inside and the outside of the hexagon. For example, Davi Vieira shared his opinions on implementing hexagonal architecture with Java in a book (Vieira, 2021).
- Other architectural styles are also testable: other styles are posed as “not testable” or that are difficult to test, regardless, frameworks are set to use the famous Model-View-Controller.
Being said that, the shift to using hex architecture is mostly due to the developer experience at hand. With experience, the other points mentioned will have less impact.
Related subjects
- Gordon Skinner - Hexagonal Architecture in DDD
- Implementing Domain-Driven-Design by Vaughn Vernon - Chapter 4.
- Software architecture patterns
References
- Stenber, J. (2014). Exploring the Hexagonal Architecture. https://www.infoq.com/news/2014/10/exploring-hexagonal-architecture
- Vaughn Vernon, T. J. (2021). Strategic Monoliths and Microservices. The Addison-Wesley Signature Series.
- Vieira, D. (2021). Designing Hexagonal Architecture with Java: An architect’s guide to building maintainable and change-tolerant applications with Java and Quarkus. Packt Publishing.
Hexagonal in practice
Let’s dive into the implementation of this architectural style to translate the theory into concrete implementation. We will do that through a fictitious application that is used for scheduling posts on social media.
Problem statement
Given the number of people who are generating content for social media and making it a business is increasing, the need for automated tools to support the day-to-day work of those people also increases. Creating, scheduling, and sending content to those platforms are some of the focuses of social publisher.
Social publisher
To depict what I have implemented thinking about hexagonal architecture we will use this made up business that aims at posting content into social media, currently the application is used through the Command Line Interface and it was built using kotlin. Let’s dive into the features:
- Create posts and focus on the content
- Delete posts
- Schedule posts to be sent based on a date and time
- Send posts to social media (X.com is supported for the time being)
The source code for social publisher is available on GitHub.
Structure overview
The packages of the application were split into application and adapters. The aim was to be strict with the naming from the image and explanation from Alistair in his interpretation of the architecture. The application has all the business logic needed to fulfill the requirements of scheduling and posting. The adapters, on the other hand, were split into two: the inbound and the outbound. The idea is as follows:

Inbound are the adapters that offer input to the application. In this case, it is only the CLI. Outbound represents the output that the application writes to. In this case, the CLI as well as storing the data in CSV.
src/main/kotlin/
├── Main.kt
├── adapters
│ ├── inbound
│ │ └── cli
│ │ ├── CliFactory.kt
│ │ ├── Configuration.kt
│ │ ├── Post.kt
│ │ ├── Poster.kt
│ │ └── scheduler
│ │ ├── Scheduler.kt
│ │ ├── SchedulerCreate.kt
│ │ ├── SchedulerDelete.kt
│ │ └── SchedulerList.kt
│ └── outbound
│ ├── cli
│ │ └── CliOutput.kt
│ ├── csv
│ │ ├── FileSystemConfigurationRepository.kt
│ │ ├── FileSystemPostRepository.kt
│ │ └── FileSystemSchedulerRepository.kt
│ ├── inmemory
│ │ ├── ConfigurationInMemoryRepository.kt
│ │ ├── InMemoryPostRepository.kt
│ │ └── InMemorySchedulerRepository.kt
│ └── social
│ ├── CouldNotCreateTweetException.kt
│ ├── CreateTweet.kt
│ ├── DeleteTweet.kt
│ └── TwitterCredentialsValidator.kt
└── application
├── Messages.kt
├── Output.kt
├── configuration
│ ├── ConfigurationGivenHasInvalidProperty.kt
│ ├── Create.kt
│ └── List.kt
├── entities
│ ├── ScheduledItem.kt
│ ├── SocialConfiguration.kt
│ └── SocialPosts.kt
├── persistence
│ ├── PostsRepository.kt
│ ├── SchedulerRepository.kt
│ └── configuration
│ ├── ConfigurationRepository.kt
│ └── MissingConfiguration.kt
├── post
│ ├── Create.kt
│ └── List.kt
├── poster
│ └── Executor.kt
├── scheduler
│ ├── Create.kt
│ ├── List.kt
│ ├── SocialMedia.kt
│ └── filters
│ ├── Criterion.kt
│ ├── DateTimeValidation.kt
│ ├── StartDate.kt
│ └── UntilDate.kt
└── socialnetwork
├── CreateTweet.kt
├── DeleteTweet.kt
├── MissingConfigurationSetup.kt
└── SocialThirdParty.kt
As previously mentioned, the structure of the application focuses only on representing the architectural style to communicate with maintainers how the code should be structured.
Testing approach
Given an already defined architectural style, the testing strategy also has already structured boundaries to be followed. In this structure, the application is tested based on the boundaries defined at the architectural layer.
For example, adapters are tested in isolation, which helps with testability of edge cases and granular complexity. The inbound, which is used here, is tested through a CLI application. The outbound adapters, defined as the adapters that talk with the external world, are also tested in isolation. The last layer is the e2e testing that is done using the defined adapters in the configuration. Later on, I found that Nat Pryce depicts this in detail.