Hexagonal Architecture
with Symfony
@matthiasnoback
info@matthiasnoback.nl
Slides are onTwitter
Somebody's wrong on the internet
Somebody's wrong on the internet
I'm one of them
This is not to say that we shouldn't listen to any
advice!
Where does advice come from?
Experience
● You look back on a recent project that went well
● You look at your choices and consider them the
cause of the project's success
● You tell other people to make the same choices.
People will copy your choices
They fail
"They got it all wrong, just do this!"
Don't follow anyone
Listen to your code
Listen to its design
Easy to move?
Easy to test?
Easy to add a
constructor
argument?
Easy to
rename?
Collect and share heuristics
Heuristics?
What worked well
In which situation
And what's a good rule of thumb for it
Should you...
Use façades?
Use Yaml?
Write methods you can call with 0, 1 or 2 arguments?
Use middlewares?
Use PSR-7?
Over-engineer your project using hexagonal architecture?
Write about what your experience
Change is really hard for most
software projects I've encountered
Reasons for change
Framework integration code
Reasons for change
Remote service calls
Reasons for change
Domain model
Single responsibility principle
for architecture
What changes for the same reason
should be grouped together
Examples
● All the things related to your framework
● All the things related to your domain model
● All the things related to your database
● ...
The most important distinction is...
Not too many groups
Domain vs Infrastructure
● Model
(entities, value objects)
● Use cases
(application services)
● Interfaces for boundary
objects
● Framework-specific code
● Implementations for
boundary objects
● Web controllers, CLI
controllers, etc.
Step 1
Introduce layers
Step 1: Introduce layers
Web framework
Domain logic
Database integration
Introduce layers
Web framework
Domain logic
Database integration
InfrastructureDomain
Step 2
Define ports and adapters
(Hexagonal architecture; Alistair Cockburn)
Determine actors
Application
Primary actor:
User
Secondary actor:
Database
Primary actor:
User
Secondary actor:
Remote
webservice
Primary actor:
Cronjob
Make a distinction...
Between the intention for communication,
and the supporting implementation
Examples
The user can buy a ticket
Examples
We have a TicketsController with a
buyTicket action. It gets the logged in user from
the session and gets the user's address from the
submitted form data.
Examples
We need to persist an order
Examples
We store order data in an orders table in our
MySQL database. We use Doctrine DBAL to talk
with that database.
Ports
Buyaticket
Persistanorder
Adapters
Buyaticket
Persistanorder
HTTPadapter
SQLadapter
Advantages
By separating domain from infrastructure code you
automatically increase testablity
Advantages
You can replace an adapter without
affecting the ports
Advantages
You can postpone the choice for
database vendor, framework, ORM, etc.
Advantages
You can more easily keep up with
the change rate of framework-specific code
Advantages
Or replace the framework altogether...
Sources
● Alistair in the "Hexagone": https://www.youtube.com/watch?v=th4AgBcrEHA
● My upcoming book "Advanced Web Application Architecture"
https://leanpub.com/web-application-architecture/
● Nat Pryce, Steve Freeman - Growing Object-Oriented Software, Guided by Tests
● Vaughn Vernon - Implementing Domain-Driven Design (see the chapter about
Architecture)
Questions?
Thank you!
@matthiasnoback
info@matthiasnoback.nl

Hexagonal Symfony - SymfonyCon Amsterdam 2019