Hexagonal Architecture or Ports and Adapters Architecture

When developing an application, the first critical step would be to choose a development architecture. By choosing the right and the most suitable architecture, you will be able to avoid such issues as duplicate code, loss of time (spent on adding new functionality), testing issues, implementation of changes to the existing code, debugging and many others. 

Hexagonal architecture is a perfect example of a convenient and efficient solution. The approach offered by this architecture type allows developers to change the used frameworks, databases and other work elements simply by adding a new adapter. This is why hexagonal architecture is often called ports and adapters architecture. So how exactly does it work and what makes it so good? Let’s have a look.

Hexagonal Architecture or Ports and Adapters Architecture

The structure of hexagon architecture and its principle of operation

When we say “hexagon”, we immediately think of a geometric figure with many angles. Hexagonal architecture implies that every edge of this figure is a port that helps the application communicate with the environment by either receiving or sending the data. In this way, by changing the port realization, we can change the required technology or logic. Thus, all business logic of an application will be concentrated within this figure and will be independent of the external frameworks, databases or services that our program communicates with.

Below you can see an example of such an app:

In this architecture, an adapter takes the role of an intermediary between the realization of certain technology and the corresponding realization of the application’s port.

Let’s see how the app components interact with each other upon choosing this development method:

UserControllerAdapter passes the command for the port realization to UserController (the realization is inside the hexagon that represents the business logic of our app). Because UserControllerAdapter passes the control to the UserController, both the adapter and the port are called the drivers. 

On the other side of the figure, there are the driving port and adapter (the operated): IUserOperations and UserRepositoryAdapter correspondingly. UserRepositoryAdapter implements UserRepository and contains a specific CrudUserRepository realization.

In this way, when the port receives a UserController command (such as to find a user), this port, in correspondence with the received command, will involve the execution thread for this command. As a result, IUserOperations will be used and, with the help of UserRepositoryAdapter, it will perform the corresponding instruction.

Our system turns out to be really simple yet efficient due to the possibility of adding new ports and adapters. The only thing that developers have to do to launch the app is to “plug” the adapters in the corresponding ports and run the application.

Below you can see an image of the same app but with the use of the Spring controller and realization of a repository for storing the objects in the MySQL database.

We can see the deployment or replacement of the frameworks through the example of logging on to the abovementioned Spring framework – Spring Web, to be more precise (RestController). In order to plug it in, we need to place our adapter in the framework realization:

@RestController
@RequestMapping("/users")
class SpringRestUserController {
    private UserControllerAdapter userControlingAdapter;

    @Autowired
    public SpringRestUserController (UserControllerAdapter userControlingAdapter) {
        this.userControlingAdapter= userControlingAdapter;
    }

    @GetMapping("/{id}")
    public UserDto askForPoem(@PathVariable Long id) {
        // Forward commands to the hexagon, by using userControlingAdapter
        return userControlingAdapter.findUser(id);
    }
}

We can plug in the operable ports and adapters in the same way.

Therefore, by using the hexagon architecture, we obtain great flexibility in terms of using the third-party services, the isolation of the app’s core from the external layers, layered architecture and low connection of the app’s layers.

Want to stay updated on the latest tech news?

Sign up for our monthly blog newsletter in the form below.

Softteco Logo Footer