Welcome to the deep Dive, the show engineered to give you the
most important knowledge and insights really fast.
You provide the sources we dive in, pulling out those key
Nuggets to get you properly informed.
Today we're taking a pretty fascinating plunge into software
design, looking at something called hexagonal architecture.
Our mission, and we're guided by the excellent source you sent
over, specifically a nine hexagonalarchitecture.pdf by
Marco Tulio. Valente is basically to
demystify this pattern, well, unpack its core ideas, look at
the benefits, which are quite surprising sometimes, and show
you why it's such a well, a game changer for building software
that lasts and adapts. Exactly.
And it's not just another buzzword.
You know, it's, it's really a fundamental way to think about
structuring applications so they stay robust, adaptable, and
maybe most importantly, testable over time.
It's about building for the long haul.
And you are definitely going to get some clarity here.
We'll even touch on why it's called hexagonal.
That's always a fun bit and how this idea helps solve some
really common and developer frustrations.
But let's start at the beginning.
Where did this come from? So yeah, let's unpack this.
This didn't just pop up recently, hexagonal
architecture. It was first introduced by
Alistair Cockburn. He's a big name in software way
back in the mid 90s. And get this, he first shared it
on the wiki Wiki web, which if you're into tech history, that
was literally the first wiki ever.
Kind of a groundbreaking place for sharing these ideas back
then. And a real piece of Internet
history there. Definitely.
And at its heart it shares a lot with other ideas like say, clean
architecture, right? The goals are similar, high
cohesion, low coupling. Exactly.
Keep things that belong together together, and make sure
different parts aren't too tangled up.
But what's the real kicker here? The core idea that makes it so
different, especially for making adaptable systems and making
testing easier? The real aha, the moment, I
think, is how it forces this. You could call it strategic
indifference. It does this with a really clear
separation. You basically split your code
into two camps. You've got your domain classes
on one side. That's your core stuff, the
business logic, the rules that make your software unique.
Then on the other side you have external classes.
This is everything that talks to the outside world.
The UI, databases, maybe external API's, payment systems,
message queues, all that and the absolute key rule.
The foundation is your domain classes must never deend
directly on those external classes.
Your core logic shouldn't care if it's talking to SQL Server or
Postgres, or if the UI is web or mobile.
Strategic indifference. I like that.
So if the domain is kept independent like that, what's
the biggest practical win for, say, a development team or the
business itself? What does that separation really
unlock? It's really about future
proofing. That's the big one.
Because the core logic is decoupled, you get incredible
flexibility. Think about it.
Maybe the company wants to switch database vendors or
completely redo the UI from, I don't know, a desktop app to a
web app, then add a mobile app later.
Usually those changes ripple through everything, right?
You end up rewriting core logic. Yeah, that sounds painfully
familiar. But with hexagonal, that core
domain logic, it stays mostly untouched.
It's like having this universal brain for your software that can
just plug into different technologies without needing a
major operation. And it means you can even reuse
those valuable domain classes across different platforms.
Same business rules for web and mobile for instance.
OK. And I can immediately see how
that would make testing much, much easier.
If the core rules don't care about the database or the UI,
testing them must be simpler. Oh, absolutely, massively
simpler. When your domain classes are
isolated from all that external mess, how data is stored, how
users click buttons, writing tests for your actual business
logic becomes much faster, easier, and way more reliable.
You don't need to spin up a whole database or fake AUI just
to check if your calculation is right.
Test the core rules in isolation.
It speeds things up. Cut sound bugs.
Huge win. That makes total sense.
So for someone trying to picture this, how is it usually
visualized? Is there a standard diagram?
Yeah, there is. The most common way is using 2
concentric hexagons, like a smaller hexagon inside a larger
one. Your domain classes, the core
logic, they live right in that inner hexagon, then surrounding
them in the outer hexagon. That's where the adapters live.
We'll get to those. And then everything, external
databases, UIS, other services, they live completely outside
both hexagons. They only interact through
defined boundaries. That image of the nested
hexagons is pretty iconic. But why hexagons?
Why that shape, specifically? Cockburn had a reason, didn't
he? Something about the faces He
did. Yeah, it's actually quite neat,
Cockburn said. The shape wasn't random.
Each face of the hexagon represents a different reason or
interface for the application to talk to the outside world.
So you might have one face for user interaction, another for
saving data, another for talking to a payment system, maybe one
for sending notifications. It helps visualize those
distinct connection points. The different ports essentially.
Exactly. Which leads us nicely to what
Cockburn himself later called the real heart of it, ports and
adapters. So what's a port here?
Not a network port, obviously, right?
Not physical. In software terms, a port is
basically an interface in your programming language.
Things like a Java interface or AC Sharp interface.
It's a contract. It defines a set of operations
or capabilities, either things the domain provides to the
outside or things the domain needs from the outside.
OK. So it's a contract.
Yeah, and there are two main types.
First, provided ports, sometimes called provided interfaces.
These handle communication flowing from outside into the
domain. They define the services the
domain offers, like if an external system wants to search
for a book in our library example, it uses a provided port
that exposes a search books method.
It's the domain's API basically. Got it outside in.
Then you have required ports or required interfaces.
These are the opposite. They're used when the domain
needs something from the outside world.
They declare capabilities the domain depends on.
So if the domain needs to save data, it doesn't know how to
save to a specific database, it just uses a required port that
says hey I need something that can save this data.
OK, so the ports are the contracts, the definitions, then
the adapters must be the things actually doing the work, making
the connections. They sit in that outer hexagon,
kind of mediating everything like translators.
Translators is a great way to put it.
Yes, the adapters of the translators, they live in that
outer hexagon bridging the gap between the domains abstract
ports and the concrete real world technologies.
And they work in two main ways. First, they take calls from an
external system, like a REST request coming in, and they
translate that into a call to the right method on one of the
domains provided ports. The adapter knows REST, but the
domain only knows its own business operation defined by
the port. It decouples the domain from
HTTP, Jason, all that stuff, right?
Second, adapters handle calls going the other way, from the
domain out to external system. When the domain uses a required
port, like I need to save this, an adapter catches that.
It then translates that abstract request into specific commands
for whatever external system is plugged in.
Maybe SQL commands for a database, or calls to a third
party API. Those adapters handling data
persistence? They're very often called
repositories. That really clarifies the roles.
To make it super concrete, let's use that library management
system example from the source. Can you walk us through a
typical interaction like checking out a book?
Sure thing. So imagine the core logic is say
a loan service inside our domain hexagon.
OK, a user clicks check out book on a web page.
That's the external interface. The request hits a web adapter
living in the outer hexagon. This adapter knows web stuff,
but it doesn't talk directly to the loan service.
Instead it knows about a provided port on the domain,
maybe one that defines A checkout book, book head, user
read operation. The web adapter takes the web
request details and calls that checkout book method on the
port. So the web adapter acts like a
bouncer, taking the web request and presenting it cleanly to the
domain via that provided port. Exactly.
Perfect analogy. Now the loan service inside the
domain gets this checkout book call.
It needs to apply business rules.
Is the book actually available? Does the user have too many
books out already? Stuff like that.
To do this it needs data, but it doesn't know about databases.
It uses a required port, maybe a book repository port or user
repository port. This port might define methods
like find book buyed or get user account status.
So the loan service calls say find book buyed on its required
port and SQL database adapter. Another adapter in the outer
ring implements this port. It receives the call, translates
find book by into an actual SQL query, runs it against the
database which is outside everything, gets the results,
and sends the book data back to the loan service.
The loan service gets the info it needs, completely unaware it
came via SQL. OK, so the domain asks it's
required port for data and an adapter fetches it from the real
database. Then, assuming the rules pass
and the book can be checked out, the domain needs to record that,
right? How does that happen?
Good. Point once the loan service
decides yes, checkout approved, it needs to update the state.
Maybe mark the book is loaned out, update the user's record
again. It doesn't touch the database
directly, it uses its required ports again.
Book repository port. User repository port may be
calling methods like save book, updated book or save user loan,
loan details. The SQL database adapter
intercepts these calls, translates them into SQL you
date or insert statements and executes them against the
database. The change is saved and that
whole cycle really shows the flow.
External system adapter provided port domain logic and then
domain logic required port adapter tan with external system
the domain stays clean. If tomorrow we want to use a No
SQL database, we just write a new No SQL adapter that
implements the same required repository ports.
The loan service doesn't change at all.
It really is a robust design. You can see the flexibility.
And Speaking of names, it's interesting that Cockburn
himself later suggested calling it Ports and Adapters
Architecture. Wasn't it back in 2005?
He did, Yeah. He apparently had this
realization, thinking, wait, the faces of my Hexagon?
Those are the ports and the things connecting to hexagons.
Those are the adapters. He felt Ports and Adapters was
maybe a more direct, descriptive name for what's actually going
on under the hood. Makes sense, it's pretty
literal. It is, but you know how things
go. By that time, hexagonal
architecture had already caught on, The visual was strong, and
it just sort of stuck. It's still the name most people
recognize, even if ports and adapters might be slightly more
explanatory. Sometimes the catchy name wins.
So wrapping this up, what you've really got with Hexagonal
architecture, or ports and adapters if you prefer, is this
powerful pattern for getting high cohesion, low coupling, and
much better testability. It all boils down to that strict
separation in between your core business logic, the
intermexagon, and everything external mediated by those ports
and adapters. It makes your software flexible,
resilient to change. Exactly.
And if you think about the bigger picture, an architecture
like this really changes how you approach software longevity.
You're building systems that are inherently more adaptable, more
resilient to the inevitable shifts in technology down the
road. It's about building something
that can truly last. Well, thank you for joining us
on this deep dive today. It's been fascinating unpacking
hexagonal architecture using the source you provided.