2. Foreword
● I call myself Tung, & you can do that too!
● I identify as an Engineer
● Please feel free to interrupt me anytime for any question :)
2
3. Agenda
● A Long Introduction
○ What is an Architecture?
○ Backend Architectures
● Hexagonal Architecture
○ The Hexagon
○ The Actors
○ The Ports
○ The Adapters
● Summary, Pros, & Cons
3
4. What comes to your mind when you hear “architecture”?
● That depends!
● The off-the-top-of-one’s-head answer varies depending on:
○ Your background
○ Your most recent / pending task
○ Your pain point at the moment
○ …
4
12. There are too many!
● The point is that these architectures are not mutually exclusive
● The frontend - backend boundary could be very fluid
○ “Backend” can use template engine to render web pages
○ “Frontend” can run code on the server to render parts of the pages there
● How small a service has to be to be called “micro”?
○ Micro services architecture with only 1 big service
○ “Nano” services architecture with lazy services
■ & tons of mappers to convert all the DTOs to-and-fro
12
13. Nothing is perfect!
● A service, reasonably sized
● 3-layer Controller - Service - Persistence
● & still a big ball of mud in there
→ These architectures are just ways to see, to organize things
13
14. Even hexagonal architecture
“Ports & Adapters pattern says nothing about the structure of the inside of the
hexagon. You can have layers… you can have components by feature… you can
have spaghetti code… you can have a Big Ball of Mud… you can apply DDD
tactical patterns… you can have a single CRUD… it’s up to you.”
14
16. The hexagon
● The core, pure business logic
● Technology agnostic
→ Could not be 100% so, as it still has to be written using a programming
language and therefore, influenced by that language
16
17. The actors
1. Drivers / Primary Actors → trigger interaction
2. Driven / Secondary Actors → are triggered by the application
a. Repository: 2-way exchange of info
b. Recipient: 1-way from application
● For knowing which kind is the actor in an application-actor interaction, ask
yourself “who” triggers the conversation
○ If the answer is “the actor” then it is a driver
○ If the answer is “the application” then the actor is a driven actor
17
19. The ports
● Ports are the application boundary, in the picture a port is an edge of the
hexagon
● From the outside world, actors can only interact with the hexagon ports, they
shouldn’t be able to access the inside of the hexagon
● An important thing to remark is that ports belong to the application
● Driver ports → API, features that the application provides to outside world
● Driven ports → SPI needed, dependencies of that application
19
20. The adapters
● Given a port, there may be an adapter for each desired technology that we
want to use
● Adapters are outside the application
● A driver adapter uses a driver port interface, converting a specific
technology request into a technology agnostic request to a driver port
○ E.g. from a REST call to a java method call (Controller class calls Service class)
● A driven adapter implements a driven port interface, converting the
technology agnostic methods of the port into specific technology methods
○ E.g. from a java method call to a push to a message queue (Service class calls Queue Client
class)
○ or from a java method call to a SQL query (Service class calls Repository class)
20
23. Summary of hexagonal architecture
1. The Hexagon → the application
a. Driver Ports → API offered by the application
b. Driven Ports → SPI required by the application
2. Actors → environment devices that interact with the application
a. Drivers → application users (either humans or hardware/software devices)
b. Driven Actors → provide services required by the application
3. Adapters → adapt specific technology to the application
a. Driver Adapters → use the drivers ports
b. Driven Adapters → implement the driven ports
23
24. The Main Component
This component will run at startup and it builds the whole system doing the
following:
● It initializes and configures the environment (databases, servers, …)
● For each driven port:
○ It chooses a driven adapter implementing the port, and creates an instance of the adapter
○ It creates an instance of the application injecting the driven adapters instances into the
application constructor
● For each driver port:
○ It chooses a driver adapter that uses the port, and creates an instance of the adapter, injecting
the application instance into the adapter constructor
○ It runs the driver adapter instance
24
25. Pros
Flexibility & immunity to technology evolution
● Swapping between different technologies is easy
○ For a given port, you can have multiple adapters, each one using a specific technology
○ For choosing one of them, you just have to configure which adapter to use for that port
● The technology you want to upgrade is located at an adapter outside the
application
○ Technology evolves more frequently than business logic does
○ You just have to change the adapter
○ The application itself remains immutable because it doesn’t depend on adapters
25
26. Pros
Delay technological decisions
● Focus just on business logic
○ Start with the application itself (ports are part of the application)
○ Choose a technology later, & create an adapter for it
26
27. Cons
Complexity
● A lot of modules and explicit dependencies defined between them
○ Modules in the sense of Maven / Gradle modules / subprojects
○ Explicitly create the separation between different elements
■ E.g. you can’t “accidentally” importing an adapter class into the application
● At least, there will be one module for the hexagon, one module for each
adapter, and one module for starting up the whole project:
○ The hexagon depends on nothing
○ The adapters depend on the hexagon
○ The starting-up depends on all of them
27
28. Cons
Commitment
● The team needs good agreement & strong discipline to follow the pattern
○ It’s just too easy to use fancy framework utilities & dirty the core
○ For example, lots of things have to be wired up manually, while all it takes is a single Spring
Boot annotation to do it all
28
29. Parting words
● Actor → Adapter → (Port) Hexagon
● Clear dependency direction & pure logic business code
○ Testing is just a breeze
● And at what price?
○ Complexity:
■ Numerous modules
■ Need for internal mappers to map DTOs between components
○ Compromises:
■ Should we write those boilerplate getters & setters, or relax & use Lombok?
■ We want the fancy Spring Boot Configuration Properties but the Config classes are part
of the hexagon?
29