Hexagonal architecture analysis

Architecture
Leon Cordero

The hexagonal architecture is a design pattern that allows the developer to focus on the business domain and testability by creating loose couple components for different peripheral attributes such as databases, api, messaging, etc. It does it by defining interfaces called ports with a simple responsibility, and their implementations called adapters.

For example, to create an order in an ecommerce system, the external interface, internal representation or the database schema have a different representation of an order depending on the needs. The design pattern has a component called adapters to establish communication between API layer and the domain layer, and from the domain layer to the storage layer, adapters usually implement an interface called port defined in the domain layer.

system
    application
        ports
            IOrderRepository.kt
            IOrderApi.kt
        order
            Order.kt
            OrderService.kt
    storage
        OrderEntity.kt
        OrderRepositoryAdapter.kt --> implements IOrderRepository.kt
        OrderRepository.kt
    api
        OrderResponse.kt
        OrderRequest.kt
        OrderApiAdapter.kt --> implements IOrderApi.kt
        OrderController.kt

The idea is that those adapters deals with the complexity of mapping from one layer to another, this way your application layer can stay clean and only focus on what really matters.

The unknown

Hexagonal Architecture is quiet related to DDD, it helps you define and apply a good domain across your application, nevertheless, I found it extremely difficult to implement when you have little knowledge about the problem, in this article I explain how difficult could be to define a good hexagonal architecture when you don’t know the domain very well.

In this repository I created two time the same application, one in kotlin the other one in go to try out the hexagonal architecture, both with completely different contexts.

Kotlin is the language I use constantly at work and I feel confortable working with it. Creating the kotlin version was partially easy, I knew the problem very well and I knew the tools. When I started the go part, it was a bit more complicated, defining a good package structure was difficult, my lack of expertise in the language slowed me down. After doing both version I can start any of them from scrat again and the result will a be done faster, with much better code and architecture.

What I want to say with this point, is that the capacity to work with a tool and the domain expertise will change the way you interact with a project. When any of both cases is not present, changing the code will cause big change applification.

Early optimisation

Starting a new project is not only about the unknowns, but effects of them when you get to learn something new. If you have been working before in a green field project, you know that big fundamental changes are quiet often at the beginning of the development, and as long as the application keeps growing it keeps maturing those big changes start being less frequents, all this assuming you don’t do a big design in front, and you experiment a bit.

Moving forward and experimenting, getting your time to learn, will help you to understand what are the
wrong assumptions, and fix them. Now imagine, that for any new functionality added to the new project, and every time you find something is wrong and you have to change everywhere?

From one side, a design like hexagonal architecture could help you to apply fixes easier, the isolation and inversion of control helps you to only apply changes where is needed, but this is true only when the fix is easy, any fundamental mistake will cost time. The same happens with new features added, simple business rules are easy to implement, but new e2e workflows are extremely costly.

Conclusion

Starting a new project without good business knowledge around the team, could lead to a lot of mistakes that will be fixes early in the development lifecycle, locking yourself to design pattern that force you to create a lot of abstractions could be a really painful approach, try something in the middle to start, the onion architecture help to get the benefits of a good separation of concerns but with fewer abstractions to maintain, long the road once the project mature and there is good business knowledge in the team you can start looking to slowly move to hexagonal architecture if really needed.