hexagonal architecture message-oriented software design
TRANSCRIPT
![Page 1: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/1.jpg)
HEXAGONAL ARCHITECTURE Message oriented software design
By Matthias Noback
![Page 2: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/2.jpg)
ARCHITECTUREWhat's the problem?
![Page 3: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/3.jpg)
!!!
Nice app
![Page 4: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/4.jpg)
!!!
Sad app
![Page 5: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/5.jpg)
Your brain can't handle it
M V C ?
![Page 6: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/6.jpg)
Coupling to frameworks and libraries
!!!
![Page 7: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/7.jpg)
How do you start a new project?
Pick a framework
Install a skeleton project
Remove demo stuff
Auto-generate entities
Auto-generate CRUD controllers
Done
"It's a Symfony project!"
![Page 8: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/8.jpg)
That's actually outside inThe boring stuff
The interesting stuff
SymfonyDo
ctrine
RabbitMQ
Redis
Angular
![Page 9: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/9.jpg)
Slow tests
DB
Browser
Message queue
Key-value
Filesystem
![Page 10: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/10.jpg)
Why do frameworks not solve this for us?
Because they can't ;)
![Page 11: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/11.jpg)
Frameworks are about encapsulation
![Page 12: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/12.jpg)
Low-level API
$requestContent = file_get_contents('php://input'); $contentType = $_SERVER['CONTENT_TYPE']; if ($contentType === 'application/json') { $data = json_decode($requestContent, true); } elseif ($contentType === 'application/xml') { $xml = simplexml_load_string($requestContent); ... }
![Page 13: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/13.jpg)
Nicely hides the details
$data = $serializer->deserialize( $request->getContent(), $request->getContentType() );
![Page 14: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/14.jpg)
Low-level API
$stmt = $db->prepare( 'SELECT * FROM Patient p WHERE p.anonymous = ?' ); $stmt->bindValue(1, true); $stmt->execute(); $result = $stmt->fetch(\PDO::FETCH_ASSOC); $patient = Patient::reconstituteFromArray($result);
![Page 15: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/15.jpg)
Hides a lot of details
$patient = $repository->createQueryBuilder('p') ->where('p.anonymous = true') ->getQuery() ->getResult();
![Page 16: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/16.jpg)
What about abstraction?
![Page 17: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/17.jpg)
$patient = $repository->createQueryBuilder('p') ->where('p.anonymous = true') ->getQuery() ->getResult();
Concrete
Concrete
Concrete
![Page 18: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/18.jpg)
$patients = $repository->anonymousPatients();
Abstract
Nice
DIY
![Page 19: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/19.jpg)
Coupling to the delivery mechanism
![Page 20: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/20.jpg)
public function registerPatientAction(Request $request) { $patient = new Patient(); ! $form = $this->createForm(new RegisterPatientForm(), $patient); ! $form->handleRequest($request); ! if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($patient); $em->flush(); ! return $this->redirect($this->generateUrl('patient_list')); } ! return array( 'form' => $form->createView() ); }
Request and Form are web-specific
EntityManager is ORM, i.e. relational DB-specific
![Page 21: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/21.jpg)
Reusability: impossible
![Page 22: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/22.jpg)
Some functionality
The web
The CLI
![Page 23: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/23.jpg)
Some functionality
Run it
![Page 24: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/24.jpg)
Lack of intention-revealing code
![Page 25: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/25.jpg)
data
data
data
![Page 26: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/26.jpg)
public function updateAction(Request $request) { $patient = new Patient(); ! $form = $this->createForm(new PatientType(), $patient); ! $form->handleRequest($request); ! if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($patient); $em->flush(); ! return $this->redirect($this->generateUrl('patient_list')); } ! return array( 'form' => $form->createView() ); }
from the HTTP request
copied into an entity
then stored in the database
What exactly changed?!
And... why?
![Page 27: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/27.jpg)
R.A.D.
Rapid Application Development
B.A.D.
B.A.D. Application Development
![Page 28: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/28.jpg)
In summary
Coupling to a framework
Coupling to a delivery mechanism (e.g. the web)
Slow tests
Lack of intention in the code
![Page 29: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/29.jpg)
THE ESSENCEof your application
![Page 30: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/30.jpg)
The essence
Other things
![Page 31: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/31.jpg)
The "heart"?
![Page 32: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/32.jpg)
"The heart of software is its ability to solve domain-related problems for its users.
–Eric Evans, Domain Driven Design
All other features, vital though they may be, support this basic purpose."
![Page 33: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/33.jpg)
What's essential?
Domain model
Interaction with it
Use cases
![Page 34: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/34.jpg)
What's not essential?
![Page 35: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/35.jpg)
“The database is an implementation detail”
–Cool software architect
![Page 36: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/36.jpg)
The core doesn't need to know about it
!!!
![Page 37: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/37.jpg)
!!!
What about interaction?
!
![Page 38: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/38.jpg)
The core doesn't need to know about it
!!!
![Page 39: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/39.jpg)
Infrastructure
The world outside
!!!
Web browser
TerminalDatabase
Messaging
Filesystem(E)mail
![Page 40: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/40.jpg)
Mmm... layers Layers allow you to
separate
Layers allow you to
allocate
Layers have
boundaries
Rules for crossing
![Page 41: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/41.jpg)
Rules about communication
Actually: rules about dependencies
![Page 42: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/42.jpg)
The dependency rule
–Robert Martin, Screaming Architecture
![Page 43: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/43.jpg)
What crosses layer boundaries?
Message
![Page 44: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/44.jpg)
MessagessomeFunctionCall( $arguments, $prepared, $for, $the, $receiver );
$message = new TypeOfMessage( $some, $relevant, $arguments ); handle($message);
![Page 45: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/45.jpg)
What about the application boundary?
The app
Messag
e
The world outside
![Page 46: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/46.jpg)
How does an app allow incoming messages at all?
By exposing input ports
Routes Console commands
A WSDL file for a SOAP API
![Page 47: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/47.jpg)
![Page 48: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/48.jpg)
![Page 49: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/49.jpg)
Ports use protocols for communication
Each port has a language of its own
![Page 50: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/50.jpg)
Web (HTTP)
![Page 51: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/51.jpg)
Messaging (AMQP)
![Page 52: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/52.jpg)
HTTP Request
Form
Request
Controller
Entity
Value object
Web p
ort
Tran
slate
the re
quest
Repository
![Page 53: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/53.jpg)
Adapters
The translators are called: adapters
![Page 54: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/54.jpg)
"Ports and adapters"
Ports: allow for communication to happen
Adapters: translate messages from the world outside
== Hexagonal architecture
Alistair Cockburn
![Page 55: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/55.jpg)
An example
Plain HTTP message
$_POST, $_GET,
$_SERVER, Request
POST /patients/ HTTP/1.1 Host: hospital.com !name=Matthias&[email protected]
Command
$command = new RegisterPatient( $request->get('name'), $request->get('email') );
![Page 56: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/56.jpg)
Command
$command = new RegisterPatient( $request->get('name'), $request->get('email') );
Expresses intention
Implies changeIndependent
of delivery mechanism
Only the message
![Page 57: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/57.jpg)
class RegisterPatientHandler { public function handle(RegisterPatient $command) { $patient = Patient::register( $command->name(), $command->email() ); $this->patientRepository->add($patient); } }
CommandCommand handler
![Page 58: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/58.jpg)
CommandCommand handler A
Command bus
Command handler B
Command handler C
![Page 59: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/59.jpg)
HTTP Request
Form
Request
Controller
Patient (entity)
Web p
ort
PatientRepository
RegisterPatient- Handler
RegisterPatient (command)
Infras
truc
ture
Application
Domain
![Page 60: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/60.jpg)
Change
New entity (Patient)
Entity-Manager UnitOf-Work
$patient = Patient::register( $command->name(), $command->email() ); $this->patientRepository ->add($patient);
Insert query (SQL)
INSERT INTO patients SET name='Matthias', email='[email protected]';
![Page 61: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/61.jpg)
SQL query
EntityManager
UnitOfWork
QueryBuilder
Persi
stenc
e port
Prepare
for p
ersist
ence
PatientRepository
Core
Infrastruc
ture
![Page 62: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/62.jpg)
![Page 63: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/63.jpg)
Messaging (AMQP)
Persistence (MySQL)
![Page 64: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/64.jpg)
What often goes wrong: we violate boundary rules...
![Page 65: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/65.jpg)
EntityManager
UnitOfWork
QueryBuilder
PatientRepository
Core
Infrastruc
ture
![Page 66: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/66.jpg)
RegisterPatient- Handler
Domain
Infrastr
ucture
Applicatio
n
Domain
PatientRepository (uses MySQL)
EntityManager
UnitOfWork
QueryBuilder
![Page 67: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/67.jpg)
PatientRepository (uses MySQL)
Domain
Infrastr
ucture
Applicatio
n
DomainRegisterPatient-
Handler
![Page 68: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/68.jpg)
Domain
PatientRepository (interface) Dependency
inversion
PatientRepository (uses MySQL)
RegisterPatient- Handler
![Page 69: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/69.jpg)
Domain
InMemory- PatientRepository
Speedy alternative
RegisterPatient- Handler
PatientRepository (uses MySQL)
PatientRepository (interface)
![Page 70: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/70.jpg)
"A good software architecture allows decisions [...] to be deferred and delayed."
–Robert Martin, Screaming Architecture
![Page 71: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/71.jpg)
IN CONCLUSIONwhat did we get from all of this?
![Page 72: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/72.jpg)
Separation of concerns
Core
Infrastructure
![Page 73: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/73.jpg)
CommandCommand
Command handler
Command handler
Stand-alone use cases
Command
Command handler
Intention-revealing
Reusable
![Page 74: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/74.jpg)
Infrastructure stand-ins
Regular implementation
Interface
Stand-in, fast implementation
![Page 75: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/75.jpg)
This is all very much supportive of...
See also: Modelling by Example
DDD
TDD
BDD
CQRS
![Page 76: Hexagonal architecture message-oriented software design](https://reader035.vdocuments.us/reader035/viewer/2022062412/58ef70611a28ab51468b4617/html5/thumbnails/76.jpg)
QUESTIONS?joind.in/14978FEEDBACK?