In this post, we are going to explore and define what Ports and Adapters Architecture or Hexagonal Architecture is. Furthermore we are going to provide an example of implementing Hexagonal Architecture in Spring Boot using Spring Data.
One of the main goals when developing software is to strive for decoupled code and different components. This allows for easier testing, troubleshooting, and isolation of the business logic from the infrastructure, such as database connections. Thus, the Hexagonal Architecture emerged from this idea.
What is Hexagonal Architecture?
Hexagonal Architecture, also known as Ports and Adapters Architecture, is a software architecture pattern that emphasizes the separation of concerns by dividing an application into different layers or modules. With Hexagonal Architecture, the application will have, at least, three layers:
- Application layer or domain layer. This layer contains the business logic of the application, which represents the core functionality of the system.
- Ports or interface layer: This layer defines the interfaces or contracts between the application and external systems or clients.
- Adapters or infrastructure layer. This layer contains the implementations of the interfaces or contracts defined in the ports layer, which provide the communication between the application and external systems or clients.
Spring Data is a popular framework that provides a consistent and easy way to access and manage data in a Spring-based application. You can use it in conjunction with Hexagonal Architecture to provide a modular and maintainable solution for data persistence.
Alistair Cockburn introduced the Hexagonal Architecture, and according to some researchers and authors, we can say that it has been the precursor to microservices-oriented architecture.
Representation of the Hexagonal Architecture
This architecture is usually represented by a hexagon. Where the number of sides represents a port, which will allow us to navigate to an inner or outer layer of the application, meaning that each component can be connected to another component through a “port”. The communication between the ports will always follow a specific protocol that depends on the objective or function it serves. The communication will be defined through, for example, an API.
The number of ports as well as their granularity or size is something that can vary. In some cases, a single port may be sufficient, for example, a single consumer of an event, and in other cases, we may have multiple ports, for example, for each use case.
The Adapter, which also defines a software pattern, can be defined as the glue between the components of our application and the outside world. There may be one or more adapters, and they will be responsible for exchanging information from the inside with the outside and vice versa.
The main idea behind this type of architecture is to create a central component or core surrounded by interfaces through which it can be accessed. In other words, what is proposed is a central core, which would occupy the innermost hexagon. In which the domains and repositories would be located, which would expose an API or interfaces to be able to obtain data from them.
DDD in the Hexagonal Architecture
One of the principles that could fit and work very well with the Hexagonal Architecture is Domain-driven design (DDD). This type of software development seeks to create layers through domains and develop and wrap the business logic of the application.
DDD can be applied in conjunction with the Hexagonal Architecture to create more flexible, scalable, and maintainable systems. In the Hexagonal Architecture, the concepts and components of DDD can be represented in the internal hexagons, which contain the business logic and the repositories that handle data persistence.
Advantages of Hexagonal Architecture
Framework changes
On many occasions, we may want to change from one framework, for example, a non-reactive one, to one that allows reactive programming. In these cases, this type of architecture will make it much easier for us to carry out these types of changes.
Dependency Injection
This type of architecture is well defined and coupled to use with Dependency Injection, as it will facilitate communication and access between the different layers.
Facilitate Testing tasks
The Hexagonal Architecture will allow us to have the code of our application divided and separated into layers. This separation will allow us to easily test the different parts in isolation.
Agnostic to the external world
Since the core of our application will be isolated through an API or Interfaces, it will be totally agnostic to the way it is accessed.
The application will receive an access request through a Script, Http, etc., and it will communicate between the different layers through its ports and adapters.
Differentiated Business and Infrastructure
Thanks to the use of this architecture, the business or logic of our application will be isolated from the infrastructure, being totally independent of each other.
Disadvantages of Hexagonal Architecture
Increased complexity
Having to create interfaces to communicate between the different layers often increases the complexity of the application.
The development team must be very clear about the basic principles and how to implement them, otherwise, they may make errors and create an application that is less maintainable and difficult to follow.
Maintenance
If it is a considerable-sized application, it will have many layers and these layers will have their respective Interfaces with their implementations at different levels.
This will lead to higher maintenance costs, for example, an increase in classes in Java. But thanks to this extra effort, we will have a high level of isolation between the different layers.
Example of Hexagonal Architecture with Spring Data in Spring Boot
Next, we will provide an example of this type of Architecture in Spring Boot. So let’s go to create an example of Hexagonal Architecture with Spring Data. Our application will have an API that will retrieve user data and save a user. We will store this data in an in-memory database such as H2 through Spring Data
We will divide the application into three well-differentiated layers. The first layer will be the domain layer, where the User domain object will be located.
The second layer will be the infrastructure layer, which will be responsible for the functioning of the framework. In our case, it will be in charge of creating beans and database connections.
Finally, the application layer will be responsible for the business logic.
In our example, we are not using Domain Drive Design (DDD). So the repository interface is located in the application layer, as it functions as a port. And the adapter (its implementation) is in the infrastructure layer. However, if our example were based on DDD, the repository interface should be in the domain layer.
The best way to understand this example is to take a look at our Github example.
The basic structure of the project will be as follows:
In this example, we can see the three layers of an application with Hexagonal Architecture well differentiated. It will also serve as an example of an application with Spring Data.
As we have seen in the example we created it using Spring Boot and Spring Data. We achieve communication between the different layers creating interfaces and using mappers to convert these objects.
Conclusion about example of Hexagonal Architecture with Spring Data
If you want to see an example of this architecture based on an application with Spring Data. Please, take a look at the Github repository.
I hope this article on Example of Hexagonal Architecture in Spring Data with Spring Boot has been useful. If you have any questions or suggestions, please do not hesitate to comment or contact us through Facebook or Twitter. And if you liked it, share it on your social networks.
Maybe you might be interested in the following articles:
Change default port in Spring Boot
Main methods of ArrayList in Java