I am going to create a spring boot application following the best way of hexagonal architecture.
I found many examples, each one implement the hexagonal differently. I have some questions I need to understand:
Assumptions:
I want to have three layers: domain layer, infrastructure layer, application layer
Questions:
Ports and use cases: these are interfaces and they should exist in domain layer ?
Adapters: This is the implementation of ports interfaces and should be in the infrastructure layer ?
Implementation of use case interface:
3.1 This should be in which layer ? application layer or infrastructure
layer ?
3.2 This is the equivalent of spring service (annotated with @service streotype) ?
3.3 This should call ports implementations (adapters) as attributes or the inverse ?
I am going to create a spring boot application following the best way of hexagonal architecture.
The 1st thing you have to take care of is that you will have to have a module (project) for the app (the hexagon) where you shouldn't use Spring Boot.
I want to have three layers: domain layer, infrastructure layer, application layer
Hexagonal Architecture (HA) doesn't prescribe layers, you can have whichever you want. The important thing is distinguish 2 zones: the hexagon and the outside.
The golden rule is that the hexagon doesn't depend (at compile time) on the outside.
Here there is a naming issue:
So in your case:
Ports and use cases: these are interfaces and they should exist in domain layer ?
Driving Ports are interfaces with the contracts (methods signatures) of the functionality that the hexagon offers to the outside (infra layer).
Use Cases are the implementation of driving ports interfaces.
Both should exist in the application layer, but don't expose use cases implementation to the outside (infra layer).
Adapters: This is the implementation of ports interfaces and should be in the infrastructure layer ?
It depends on the kind of ports: driving or driven.
Driving adapters are in the outside (infra layer) but they don't implement driving ports. They call the driving ports functions. For example, a REST controller.
Driven adapters are in the infra layer also. They implement the functions declared in the driven ports interfaces. For example a database adapter.
Implementation of use case interface:
3.1 This should be in which layer ? application layer or infrastructure layer ?
The use cases implementation should be inside the hexagon, in the application layer. It uses the domain layer, where domain entities exist.
3.2 This is the equivalent of spring service (annotated with @service streotype) ?
Yes.
3.3 This should call ports implementations (adapters) as attributes or the inverse ?
The use cases implementation call the functions declared in the driven ports interfaces. You inject the driven adapters (implementation of driven ports) at runtime.
Driven ports interfaces exist in the hexagon (either application layer or domain layer), so that at compile time the hexagon doesn't depend on the outside (infra layer).
For example, a driven port would be an interface for accessing the database, or for accessing an external service, or for sending messages.
Driven ports should be defined in terms of the application/domain concepts, in a technology agnostic way.
Finally, some useful links about Hexagonal Architecture:
https://hexagonalarchitecture.org/
https://alistaircockburn.com/Articles
https://jmgarridopaz.github.io/content/articles.html
https://www.youtube.com/playlist?list=PL1msPBH9ZGkhpANkreFA_teOnloVdLuCx