Book cover

Buy e-book on Leanpub

To report errors or typos, use this form.

Home | Dark Mode | Cite

Software Engineering: A Modern Approach

Marco Tulio Valente

1 What is a Hexagonal Architecture?

1.1 Introduction

The concept of Hexagonal Architecture was proposed by Alistair Cockburn in the mid-90s in an article posted on the first wiki that was created, called WikiWikiWeb (which primarily covered Software Engineering topics).

The goals of Hexagonal Architecture are similar to those of Clean Architecture, as we described in another article. However, to remember, the idea is to build systems that have high cohesion, low coupling, and that are easier to test.

A Hexagonal Architecture divides the classes of a system into two groups:

Moreover, domain classes should not depend on classes related to infrastructure, user interface, or external systems. The main advantage of this division is to decouple these two types of classes.

In this way, the domain classes do not know the technologies–—including databases, user interfaces, and any other libraries–—used by the system. Consequently, technology changes can be made without impacting the domain classes. Perhaps even more importantly, domain classes can be shared across more than one technology. For example, a system may have various interfaces (Web, mobile, etc.). Lastly, but also very important, it is easier to test the domain classes when they are decoupled from other non-business-related classes.

In a Hexagonal Architecture, communication between the classes of these groups is mediated by adapters, that is, by classes that implement the same-name design pattern we studied in Chapter 6. We will explain better the role of the adapters shortly.

The architecture is usually represented by two concentric hexagons (see the next figure). The domain classes (or business classes, if you prefer) are in the inner hexagon. In the outer hexagon, we have the adapters. Lastly, the databases and other external systems are located outside these two hexagons (and, thus, they are not represented in the figure).

Hexagonal Architecture

Cockburn justifies the use of a hexagon as follows:

Each face of the hexagon represents some reason the application is trying to talk with the outside world. This is why it is concentric hexagons and not concentric circles.

Among the reasons that require communication with the outside world, we can mention the following: interacting with the users (via some interface, whether it is Web, mobile, console, etc.), persisting data, sending data to other systems, etc.

1.2 Ports and Adapters

In Hexagonal Architectures, the term port designates the interfaces provided or required by the domain classes (note that the interface here means a programming language interface; for example, a Java interface).

There are two types of ports:

Finally, we have the components located in the outermost hexagon of the architecture—the adapters—that work in one of the following two ways:

1.3 Example: Library Management System

The next figure shows the hexagonal architecture of a library management system:

Hexagonal Architecture of a Library Management System

In the figure, we observe that users can access the system using three interfaces: Web, mobile, and through an external system. In any case, this access is mediated by the adapters at the top of the figure. These adapters call methods defined in a port (or interface) provided by the domain. For example, this interface might define methods for searching for books, making loans, registering users in the library, etc. These methods are implemented by domain classes.

To fulfill its mission, the domain also needs to persist some data. For that, it can use the services defined in a required port (or interface), which defines methods for saving and retrieving book data, saving and retrieving loan data, etc. An adapter in the bottom part of our figure implements these methods by accessing a relational database. Thus, this database is an external system located outside the two hexagons.

In Hexagonal Architectures, we can have several required and provided ports, which are all located in the inner hexagon, along with the domain classes. Moreover, we have two types of adapters: (1) adapters that call methods defined in ports (or interfaces) implemented by the domain; (2) adapters that implement the methods of a port (or interface) required by the domain.

1.4 Conclusion

In 2005, Cockburn suggested that his architecture could also be called Ports and Adapters Architecture, with the following justification:

I finally had this aha! moment (June 2005) in which I saw that the facets of the hexagon are ports and the objects between the two hexagons are adapters […] and so the architectural pattern is Ports and Adapters Architecture. It admits of a better explanation than what I could come up with in Hexagonal Architecture.

However, this alternative name wasn’t so successful and the architecture, probably, continues to be more known as Hexagonal Architecture.

More Info

We recommend two short articles by Alistair Cockburn on WikiWikiWeb. The first article discusses the main characteristics of a hexagonal architecture. The second article explores the concepts of ports and adapters.

You can also check out our article about Clean Architecture.

Exercises

1. In a Hexagonal Architecture, an adapter is an implementation of the same-name design pattern. And the ports? Can they be seen as being an implementation—at least approximate—of which design pattern? If necessary, consult the Chapter 6 to answer.

2. In the figure with the hexagonal architecture of the library management system, why are the user interface adapters (HTTP, GraphQL, and REST) and the persistence adapters (SQL) on distinct faces of the hexagon? Could they be placed on the same face?

3. The definition of the term hexagonal is arbitrary, as depending on the application, it can be called quadrangular, pentagonal, heptagonal, octagonal, etc. Justify this statement.

4. Next, we show the code of two domain classes that are used in the documentation of Django, a well-known framework for building web applications in Python. The code defines rules for mapping fields from these classes to columns of database tables. Does the implementation of these domain classes follow the principles of a hexagonal architecture? Justify your answer.

from django.db import models

class Musician(models.Model):
  first_name = models.CharField(max_length=50) 
  last_name = models.CharField(max_length=50)
  instrument = models.CharField(max_length=100)

class Album(models.Model):
  artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
  name = models.CharField(max_length=100)
  release_date = models.DateField()
  num_stars = models.IntegerField()

5. Describe the differences between Hexagonal and Clean Architecture (which we studied in another article).