---
title: 'The Secrets of Hexagonal Architecture - Nicolas Carlo - Bulgaria PHP Conference 2019'
source: 'https://youtube.com/watch?v=iQE_XDJVAZA'
video_id: 'iQE_XDJVAZA'
date: 2026-07-28
duration_sec: 2506
---

# The Secrets of Hexagonal Architecture - Nicolas Carlo - Bulgaria PHP Conference 2019

> Source: [The Secrets of Hexagonal Architecture - Nicolas Carlo - Bulgaria PHP Conference 2019](https://youtube.com/watch?v=iQE_XDJVAZA)

## Summary

Nicolas Carlo explains the core principle of Hexagonal Architecture (Ports & Adapters): separating domain (business logic) from infrastructure (technical details). He demonstrates how this separation makes code more maintainable, testable, and adaptable to changing requirements, using a PHP example of a poetry reader that initially reads from the filesystem and can easily switch to HTTP.

### Key Points

- **The Problem: Changing Requirements** [02:55] — A project started with filesystem storage, then switched to FTP, then to HTTP. The speaker was able to migrate quickly because the domain logic was separated from infrastructure.
- **Core Principle: Separate Domain from Infrastructure** [05:23] — The universal truth for maintainable software: identify the domain part and the infrastructure part, then separate both. Domain is the business logic; infrastructure is the technical tools (databases, protocols, etc.).
- **Example: Poetry Reader (Traditional Approach)** [09:25] — A poetry reader class mixes file reading (infrastructure) with business logic (return default poem if none found). This makes testing hard and code brittle.
- **Hexagonal Architecture Explained** [16:09] — The architecture has a domain core and an infrastructure shell. The dependency rule: everything outside depends on the inside, but the inside never depends on the outside.
- **Using Interfaces (Ports & Adapters)** [18:34] — Define a port (interface) in the domain that expresses the business intention (e.g., PoetryLibrary). Implement adapters in infrastructure (e.g., FileSystemPoetryLibrary). This inverts dependencies.
- **Initialization Recipe** [24:43] — Instantiate right-side adapters (e.g., filesystem), then the domain with those adapters, then left-side adapters (e.g., CLI) with the domain. This wires everything together.
- **Testing the Domain** [28:29] — With the architecture, testing business logic is easy: mock the port interface. No need for actual files or databases. Tests are simple, fast, and reliable.
- **Benefits and Limitations** [33:06] — Benefits: plug-and-play adapters, defer technical decisions, easy to change protocols. Limitations: doesn't prescribe folder structure; need to decide where to put files. Clean Architecture adds more layers.

### Conclusion

Hexagonal Architecture is a simple yet powerful pattern to separate domain from infrastructure, making software more maintainable and adaptable. Start by identifying the domain core and ensuring it has no dependencies on technical details.

## Transcript

put that in another but it was very
convenient to start working because I
can do that on my computer put some
files on a folder run my application and
thisif is moving so we starting working
with the file system so we get unlocked
and we starting adding features after
one month they finally came with a
protocol so they told us hey you will be
using the FTP protocol so you can you
know share files together the here are
the credentials so you need to go back
to the code one month's worth of code
and everything you have done in that
file with the file system you no need to
use the FTP
instead so I did that it was fine but
then you can guess what happened they
came back like two months in the project
with the dead like coming there is no
way we could move the deadline they came
back and I say oops it won't be FTP like
all the thing you have done that won't
work you need to use HTTP not even HTTP
HTTP so at that point what you should do
you cannot move the deadline specs are
changing that's life you should
renegotiate the scope what's really
important what needs to be done on the
first of January so your application
works this is what you need to negotiate
and maybe there are some things we
discussed we agreed on at the beginning
but there are less important however in
that case I went back to the code and
like in an hour I actually was able to
migrate everything from using FTP to use
HTTP instead and I had no regression it
was very easy for me to do that and not
only that but since the very beginning I
didn't even set up an FTP server on my
machine and either I try to mock the
other systems using HTTP to test my
application well we're still using the
file system on the development
environments and then HTTP for the
production and it's not because I'm a
10x developer or super coder or whatever
it's because I know some tricks
I want to tease you too much so I'm
gonna give you right away the
of this talk like that right at the
beginning so if there is one thing you
should retain from my talk today is this
if you want to write a maintainable
software there is one thing that is
universally true that you should do
which is first identify the domain part
identify the infrastructure part and
then you separate both of them this is
critical so let me introduce these two
terms my name is Nicolas I'm working in
Montreal Canada for a nice company named
buzz pod so at best but we do a web
application for you to search compare
and book intercity bus tickets meaning
that if I want to go from Sofia to
positive and I don't know Bulgaria
because I'm a tourist I can still use my
application and find a different kind of
buses that they do find the best the
cheapest one maybe or the fastest one
and I can still pay in Canadian dollars
or you can use that in travel to South
America for example and pay in Euros or
whatever currency you want every day at
work we use some words so when we speak
together developers project managers
marketing people customer support people
we share a vocabulary like we speak
about seeds departures
staffs round trips etc and we have the
context around this word you probably
don't understand leg the way we do in
our context however taxes fees discount
code that kind of thing you probably
have that too if you're taking money
from people if you are having a check
out part in your application you
probably have these words too regardless
all of these words there are part of our
business and we talk about these words
regardless your developer or not this is
your domain domain is or business and
one could argue that this domain exists
regardless there is a software or not
you could imagine that we have a kiosk
in every bus station in these 80
countries with someone behind with
you come see that person what are the
best available oh you have all of these
operators and here is the best one you
pay money to us we get some commission
and we make money now without software
it will hardly be profitable that that
won't be realistic software make the
business profitable but it doesn't
really matter what kind of technology we
use behind for the cubes immersion here
are some of the technologies that we use
today so for example we store things
into Redis and passe grid databases we
could have used other kind of databases
for example that doesn't really matter
this is the infrastructure the
infrastructure is what all of the tools
that we have made together to make all
of this work in real life but really the
infrastructure part is a detail meaning
that you can change it and it won't
change the business this is something we
miss Adam as developers we are here to
solve the problem we're here to build
the infrastructure to make the business
work and because of that we focus too
much on the solution and we tend to not
speak that much about the problem that
we're solving however at the heart of
our software we are solving a business
problem and it's important to keep that
separation and to put the domain part at
the heart of the software because this
part won't change or when this part
changes that means you're making your
business grow let's see that on a
concrete example so it's an example I
really like which is let's imagine we're
building a poetry as a service system
and this is prince zero our project
manager she is asking us to well as a
user I should you know get a poem from a
poetry library and if I don't get a poem
you should return me the default one
which is listed in the specifications so
let's try to do that the
usual way so if I was to do that and by
the way I need to do a disclaimer these
days since I'm at best but I mostly do
JavaScript so my PHP is a bit rusty but
the example is simple enough so you will
follow so at some point I will create a
class which I will call a poetry reader
because yes it will read some poetry and
this class it will have a public method
which I will call give me some poetry
because like I'm using the words that
were in the specification sounds fine
this thing should give me some poetry
now where do I find the point so I ask
the question this is print 0 there is
some kind of author system that will be
writing the poem somewhere on the file
system in a text file so I should really
just go and read the content of that
text file and because this is vs code so
you can see here it's a bit small but I
do actually have a text file so this
thing will work this thing will be
located in my assets folder and if I
don't have a poem well I should go use
the default poem that we agreed on which
is poem from Alastair Coburn who coined
the exact normal architecture terms
originally and then I returned that
point okay I do I make this work well at
some point I need to instantiate the
poetry read your class and then I will
just use my CLI here to see the result
of that so I will echo quash reader give
me some poetry okay let let's try that
so I told you this is this is just a
file nice so I get something it's a
French poem but wait a minute because in
French we have some accented characters
and seems that we have an encoding
problem my favorite kind of problem
so yes there is this problem and we
asked the project manager what's
happening and turns out the the file
we're receiving is not encoding using
utf-8 so we need to you know convert the
encoding and hopefully in PHP well we
have a function for that so MB convert
encoding give it the poem I want that in
utf-8 and turns out the encoding use is
a Western encoding whatever is a thing
so let's try that again and here it is
it works so classic short basic example
of what it will look like to to develop
that kind of feature traditionally we
just go and solve the problem and make
that work and that's it but there are a
couple of problems with this and the
main problem I would like to focus on it
the fact that we have mixed the domain
part with infrastructure part where is
the domain well the pwetty reader give
me some poetry this is just domain part
then the file get contents and
converting the encoding and all of that
this is infrastructure details I can
probably not ask my project manager to
read that code and understand what it
means however the rest if there is no
poem the poem then should be the default
one and return the poem this is again my
business logic that my project manager
can understand and read the code the
problem of mixing both together is that
first of all it makes the hard for you
to see what is the business logic in the
middle of all the infrastructure details
you can imagine some queries to
databases and queries to HTTP services
right in the middle of there is some
business logic here and because of that
it's hard to test the business logic
like I don't have the time to test this
but if I were to test that I will either
need to have an actual
set up that like provide me a text file
with the poem and one without the poem
so I can test the behavior of my
application in both cases and then I
will need to figure out how to listen to
the output of the CLI or I would mock
the low-level details like file get
contents so I can control what happens
here but that will be terrible and I
will need to rewrite that test every
time I need to change how I retrieve the
poem so usually it's hard to test the
business because of that so it's hard to
test the code so people don't test the
code or not all of the business
requirements and when you don't test the
business requirements when you do change
the code for any reason then it's very
likely your code will break which is a
problem also something I want to mention
some people think that this will be a
very valid refactoring you know to make
that code bit easier to read I will just
extract the infrastructure part in a
function like read encoding file take
file name and return me the poem the
path where something like that okay so
yes
that's a valid refactoring extracting a
function but that doesn't change
anything to the fact that your domain
still depend on the on the file system
here so better readability but in terms
of testing you still have the same
problem so this is not what I'm talking
about let's see how to solve that and
let's discover what is exactly null
architecture to me exactly an
architecture it's the simplest way you
could have to do exactly that to
separate the domain part from the
infrastructure it's a simplest way how
simple that simple like you can how they
do is more simple than two potatoes on
the screen
this is a simplest architecture I know
and I just didn't draw two potatoes on
the screen randomly I put the domain
part at the heart of my acute
architecture and that's because there is
one rule which is the dependency rule
and that rule says that the everything
that is outside depends on the inside
but the inside cannot depend on the
outside and this is critical that means
your domain should not know about the
infrastructure part so where is the
exact on here it is and this is
something you should know about the
exact on there is nothing about the
exact on like exact on all is a
marketing word because as I said Coburn
so we coined the term exactly
architecture originally named it ports
and adapters architecture and that will
make sense but is also a consultant I
was a consultant when you are a
consultant you need your IDs to stick in
people mind so geometrical shape it's
easier to remember like it's really
marketing thing and that's a true story
because he told us that it's an exact on
because you know it's very easy to draw
it's very symmetrical compared to like a
pentagon it has not too few sides not
too many so it's very convenient and
that's it so this is something you
should know about the executive
architecture exactly know is marketing
but the core which is inside we will see
in a moment so let's focus on the exec
on how do you make the domain not depend
on the infra but at some point I need to
go and read that file on the file system
if you're doing object-oriented
programming which I guess you are doing
if you are using PHP you should know
that we have solved that problem long
time ago using something we call
interfaces so this is an abstraction
this is your intention and this is your
business intention because yes I need to
get my poem from
poetry library whatever this poetry
library is so my code my business code
will depend on that intention and then
somewhere in the infrastructure layer I
will have an implementation and adapter
that is saying okay I will get you to
your poem an approach library and that
will be using the file system and when I
do that I switch the dependency I invert
the dependency between the
infrastructure and the domain you take
the interface you call that a port and
there you have the ports and adapters
architecture and there this is
everything that is about this
architecture you put ports inside your
domain and then you build different
adapters on the infrastructure side
super important inside your domain it's
not just any kind of interface
abstraction like it won't be an HTTP
interface it's a business oriented
interface again your intention pay
attention to the business language try
to foster that business language inside
your domain and that will be better for
everyone we have two sites for the
adapter that's just a convenient way to
distinct the two kind of adapters that
we can have the first side is on the
left and it's everything that is
exposing your application to the outside
world so that could be for example a UI
or a CLI which was my case here or it
could be a REST API and that also means
that I could plug another way to consume
my application without changing anything
about the application and by the way
tests are just another consumer of your
application in a sense so if you're
building for production for a UI for
example you at least have two kind of
consumer one being the test on the right
side you have everything that is needed
by the domain to do it stuff so typical
things are occurring things from a
database or from external web services
let's go back on our example and and try
to do that but applying exact normal
architecture for real so I will start
with the domain because I can start
coding the domain with the business
requirements that I don't care how the
thing is implementing exactly this is
like pure logic so we'll start with the
domain part in the domain I will well
create my poetry read your class again I
will keep my give me some poetry
function because this were really nice
and everyone understand that and then
when I reach it the poem this is how the
magic happen I will read the
specification again and this is saying
you should get a poem from a poetry
library and if it doesn't say that go
and talk with people try to understand
what is the logic behind what are the
words so I will just try to reflect that
in the code I got some kind of virtual
library here and this has a get a poem
method I think in a decision here then
the rest of the logic is the same if
there is no poem I should default on
Alistair Coburn poems and then I really
return the poem okay I need to get that
poetry library and that I will inject in
the constructor I don't know exactly
what is the poetry library
implementation but someone will know and
give it to me and implicitly we could
make it explicit but there is this
interface of the poetry library and it's
kind of a contract like I don't care how
is it implemented but what I do know is
this thing needs to give me a get a poem
method so you can build any kind of
poetry library as long as it provides
this contract for
this contract okay so let's move on the
infrastructure part everything is done
on the business side and now we need to
make things happen with the file system
so on the infrastructure side I will
build a file system adapter here my file
system adapter will need to know about
the domain because I will be
implementing the interface and the
interface is defined in the domain so
that's how the infra depends on the
domain part so I will do a file system
virtual library that implements the
poetry library interface and because it
implements the poetry library interface
I need to provide a get a poem public
function so let's do that and what is
the implementation of this it's the one
I had before I don't like the technical
solution still needs to happen but I
will put that solution here and all of
the concerns around encoding for example
will be here and the business doesn't
change because of that so utf-8 and is
OAD i-59 okay and I returned that point
okay so I have my domain part I have
mine adapter now I need to make that
thing connects together or it won't work
at some point in your application you
have the entry point of your application
and when you do exactly architecture we
use the three steps initialization it's
always the same recipe so I'm giving it
to you right now the first thing you do
is you instantiate the right-side
adapters the right-side adapters are the
one who provide the domain with like
capabilities so in that case the file
system virtual library this is a
lifestyle editor so I will instantiate
that and if it was an HTTP boy to
library tomorrow and I need to
authenticate this is
I will provide the configuration for
authentication I won't go in and pass
this information to my domain part it
won't care then as long as I got my
adapter I can instantiate my poetry
reader and I will pass the filesystem
poetry library in that case but you can
imagine I pass any kind of other adapter
at runtime and in the end I need to
expose that so in this example I'm using
a CLI so I will imagine that I define a
CLI adapter enjoy infrastructure and I
will pass to that adapter the domain so
this adapter doesn't do the business
logic it's the role of the exec on the
domain part but it exposed that like to
the tli for example and then when I'm
here really I have everything so I will
put the app logic and the app logic it
will use the left-side adapters so in
that case I can like echo some here is
some poetry give it some space and then
I will use my right side adapters to you
know do stuff so ask for poetry for
example or it could be anything this is
like I'm using the right side adapters
in my entry point to kickstart my
application and export that to the
outside world ok I need to go back
implement that CLI adapter so remember
the left side adapters are how we what
we use to expose the application so I
completely arbitrarily decided to name
that CLI and this should have this will
take the domain in the constructor it
will be injected so it won't know how to
actually do the logic so we'll just tour
that and it will have a method that I
call give ask some poetry and what does
this method do well it will expose
to the CLI the results of my eggs egg on
so in that case I will just echo the
result of it but really this is a point
where I could for example take input
from my user and provide that to the
eggs a column to executor logic and
return that so I have everything is in
place that should work I will call that
so 0 2 0 3 yes it works so see I've
solved the same problem but I've used a
different kind of architecture it's a
bit more code but it's not more complex
not that many much complex and I do have
time to show you how I will test the
domain part because now it's super easy
to test the domain part and all of the
business requirements I can test super
easily so for that I will use PHP unit
and I will test my part you read your
class so I can test the happy path the
default behavior which is it should give
me some poetry from the library usually
I recommend you write tests first
in that case for the flow of the talk I
write them after but it's good to start
with them first because you start from
what you wish you have also I structure
my tests with a given one then structure
arrange a third act also it's another
name for that and I start with the then
part because the then part it's the
final outputs so here I'm asking to
myself why do I wish this thing do well
I wish this thing returned me a result
that will equal to the poem I will
define okay very generic but now I know
that I need first of all the result of
my call which is the when part when part
is what are you testing exactly in that
case I get the result
a call to the give me some poetry so far
I don't really have to think I just have
to apply like the recipe okay now I have
to think a bit where do I find the
portraiture well I guess I need to
instantiate it so I will imagine that
everything is ready for it so I wouldn't
sting my poetry reader and I know
this thing takes a portrait library okay
so now I need to provide it a poetry
library and I told you that the portrait
library can really is any thing that
implements the interface so in that case
I will provide a mock and that mark
won't change it won't change for
technical reasons if that mock changes
that means my business is evolving my
intention is changing so that mock is
fine I am controlling the context so I
can test the logic of my poetry reader
and in that case I will control the get
appoint method and in that case I will
return the poem that I no need to define
so we'll give it another poem I stored
from Misawa cheeky alright so here is my
test simple to read I don't care about
the file system or anything let's try
that so I've got some PHP in it here
[Music]
yeah let's quickly do the next test so
how would that test that it returned me
the default poem if there is no poem
well the beginning is the same I start
with the then part it should equals that
poem of from Alastair Coburn from my
results what is the result
it's the same call it's usually the case
like your when part is always the same
between your tests
so I need the poetry reader again so I
really it will be the same thing that
takes a poetry library and the poetry
library again it's the same thing it's
still a mock of my interface and the one
thing that changes here is that this
mock it will return nothing so this is
how easy it is to test the different use
cases and I can run that again and it
works no when the tests work for the
first time always be suspicious so I'm
just gonna make it say something oops
okay
it feels so it works and that's it
that's how you do exactly no
architecture that's everything you need
to know and when you know that you know
all of the basics but I realize that
most of the time because it's so complex
Lee told people don't really understand
that basics and don't apply that basics
so let me finish on the prose and also
the limitation of it the first thing I
want to say there is nothing new in
everything that I said if you're doing
object-oriented programming programming
to an interface and all of the solid
principle most of them are about
interfaces really they're compatible
with that there are about that if you
follow that if you're doing functional
programming instead it's not that
different in functional programming you
easily the side effects of your system
with the i/o monad and you put that at
the edge of your system because at some
point you need to talk to the file
system or to the database so it works
this is why you are getting paid for but
you don't want that to be spread
everywhere in your application so you do
like a functional pure
core and then an imperative shell also
called the onion architecture and this
is the same domain infrastructure maybe
the difference will be on what language
do you use inside your functional core
is this just mathematical functional
monads and things like that or do you
want to express the business language
instead it's up to you the good thing
about that as you might understand you
can plug any kind of adapter to the
domain it's a plug-and-play architecture
if tomorrow I need to switch from the
FTP to the HTTP it's not more complex
because we're two month in my adapter is
like 50 lines long what I need to do is
just to provide another implementation
of the few methods using another
protocol and this is a short thing to do
that means you can defer technical
decision and this is what in my opinion
a great architect can do it's not like
when you're a good architect you have a
lot of experience with different kind of
databases so you're able to answer the
question what kind of database do we
need to use you are the senior developer
so you might you should know that my
preferred answer is we don't care for
the moment like I will give you the best
educated guess with the information we
have now but really until we are in
production do we really know exactly so
do we need to go for the fancy complex
stuff right now or can we ship fast with
a simple solution that works today that
is reasonable and if we need to change
tomorrow we will be able to do that
without it being too complex because if
I can make the change in one month and
it's still as easy to do the change it's
fine it's not fine when you know that
you're committing to a technology and if
you're committing to it in six months it
would be hard for you to change the
technology it's only the first step
though and this is a limitation I was
able to do that in 35 minutes
that means you will have a lot of
question when you apply that in actual
production code the usual question is
where do I put the files well it doesn't
tell you anything about that and I will
tell you it's up to you it depends on
the majority of your team on how you're
comfortable can you make the framework
just live in the infrastructure part it
will be ideal some people start with
like a folder domain a folder
infrastructure and split like that I
tend to prefer using something we call
the screaming architecture which is I
put the business in my folder names so
when I'm looking at the architecture of
my application oh there is search and
check out one way roundtrip you're in
the transportation business it's not
just any model-view-controller kind of
folder technical one and I don't know
what you're doing exactly but really
it's up to you I will recommend you to
go start with that and then go further
with the clean architecture it just
gives you more layers so it answers the
detailed question like okay this thing
is more to the outside world and this
thing is more like it's it's closer to
the business but not exactly where do I
put that this thing gather the existing
knowledge about the different kind of
architecture and gives you more layer
but the rule is still the same
dependency rule from the outside to the
inside so start with extracting the
domain part and make that not depend on
the infrastructure this is the first
step you need to do and finally if you
want to build a strong domain like this
domain part you will have a lot of
classes inside and more and more
business logic and to make that grow if
you're not building a prototype if
you're not in a hackathon if you're
building something you're making money
with and you aim to maintain for more
than one year I strongly recommend you
to bring your team to get into domain
driven design not really much for the
technical patterns that are interesting
but they're not the most interesting
thing
but about the importance of the language
and the concept that you can have
different models you you don't have to
have one big departure model to
represent everything in your application
but you have contexts that's it
please remember Monday at work start
thinking about domain infrastructure and
how you could separate them both thank
you very much
[Applause]
yeah we have I saved two three minutes
for the questions if you have some
please go ahead
hi thank you for a speech it was really
great but I have question it really
seems to be a domain-driven design but
you forgot to talk about application
layer and you kind of mix it together
with infrastructure would you like to
know why and I have second question more
practical from my practice so should all
exceptions be converted to domain
you
clean architecture or other kind of
architecture that introduces that player
I told you you need more layers in the
infrastructure and the application layer
in is in the middle it's more the
infrastructure side really going to
clean architecture you will you have
more information about that and
regarding the so I have an exception
should should I convert that into the
domain exceptions all the exception
including the infrastructure one no it
depends if it's a purely in frustration
it's a technical exceptions so it's fine
to have a mix of both in your
application how you do that might be
interesting to discuss but we don't have
time I will stay outside if you want to
dig into more details of that kind of
question but yes you can have both kind
of exceptions in your application
overall final question I know there is
lunch all right thank you very much
you
