Hexagonal Architecture — 1/2 — overview
A way to isolate business logic in code
The hexagonal architecture is one of the trending one way to get a clean codebase. Because we know that working with a mess is time consuming, and we prefer spending our time to produce value than to try sort out the big ball of mug. I hope this article will help you get right to the point to have a cleaner architecture of your codebase. There are ten sections divided into two parts. This first part gives an overview of the hexagonal architecture, the second will provide more in-depth details with a code sample.
Table of contents
- Ports and Adapters
- Inner Layer Isolation
- Hexagonal vs Onion vs Clean
A bit of history
Published in a blog by Alistair Cockburn in 2005
The hexagonal architecture is synonym to “ports and adapters pattern”, but nowadays “hexagonal architecture” is better known.
The term “hexagonal” comes from the graphical conventions that shows the application component like a hexagonal cell. The six borders represents the multiple interfaces that the component may expose to the external world.
The hexagonal architecture aims to :
“Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.”
In other words, it aims to isolate the business logic from the rest within the application, codebase wise, so we can focus test automation on its behaviour independently. Thus it leads to divide a system into several loosely-coupled interchangeable components, such as the business logic, the database, the user interface, test scripts and interfaces with other systems.
This approach is more likely an extension instead of an alternative to the layered architecture.
There are three principles which we must rely on :
- separate clearly the exposition, domain and infrastructure
- manage dependencies from outside in, in direction to the domain
- isolate the center / domain from the outside concerns by using ports and adapters, via interfaces
Each component is connected to the others through a number of exposed “ports”. Adapters are the glue between components and with the outside world. Concretely adapters are the implementation of the ports.
Note : “exposition” is my personal preference in terms of wording.
Based the first principle above, we can separate explicitly three main modules :
This modules is the client facing, on the left side. It allows to interact with other applications of the outside world, by exposing API (HTTP, REST, Websocket etc.) to be consumed by external application (SPA, programme or another backend). This side is the driving side, meaning it drives the domain which will apply business rules.
This module is the one we want to isolate from the rest, because it host all the business logic. Referring to the Domain-Drive-Design approach, we rely on the ubiquity language, so we would use the domain specific vocabulary.
Almost every application needs to interact with tools and/or other systems, which we call infrastructure. In this module, we want to allow the application to retrieve or send data to the outside world. The nature of interact could be any kind, and typical ones are HTTP, File System, SMTP, SQL. The infrastructure module is the driven side
In the diagram above, we can see thee 3 modules (exposition, domain and infrastructure). When structuring the code of project, we usually would separate them clearly within the codebase. From here on, we will use an example based on a web service that exposes a Note Endpoint, which will call the Note Service in the domain, which in turn uses the Note Repository to persist the note. We will see the code samples in the sample section.
Hexagonal architecture is a pattern for designing software applications. It is based on two layers, inner and outer layers, delimited by the hexagon borders from the outside. The inner must not depend on the outer. The sides of the hexagon are simply representations for ports. The hexagon is balanced with some external services on the left and others on the right. Let’s see the flow as left to right.
Ports and Adapters
Remember that hexagonal architecture is a pattern for how to structure certain aspects of the application. It’s specifically about dealing with I/O.
- I/O goes on the outside of the hexagon
- Adapters are in the grey area, gluing the center to the rest (exposition and infrastructure)
- The sides of the hexagons are the ports.
- Finally, the center is the business logic composed of services and domain.
The goal of this architecture is to structure the code so that changes are easy, safe and fast to make. We have seen the overall concept, but there are three things to keep in mind : 1) modules, 2) layers and 3) ports and adapters. Obviously this architecture is mainly focused on business code isolation from the rest, by separating clearly exposition, domain and infrastructure. You may read the second part to see how we can achieve that.
Thanks to Dan MAGIER for reviewing and helping me to clarifying some ideas in this article.