a journey from hexagonal architecture to event sourcing
TRANSCRIPT
A Journey from Hexagonal Architecture to Event SourcingCarlos Buenosvinos (@buenosvinos)
Polycon, October 6th, 2017 Barcelona
2
Who am I? Carlos Buenosvinos
• Technical Director @ XING • Consultant • +10 years on Tech Leadership
(CTO, VP of Engineering, Director) • Teams up to 100 people • E-Commerce, E-Learning,
Payments, Classifieds, Recruiting • Atrápalo (500M EUR),
PCComponentes (300M EUR)
@buenosvinos3
4
Domain-Driven Design in PHP Book Carlos Buenosvinos, Christian Soronellas and Keyvan Akbary
https://leanpub.com/ddd-in-php
I want to tell you a real story about…
5
a Company evolving its architecture.
6
Spaghetti Architecture
7
• Multiple Application Entry Points - create_user.php, delete_user.php, …
• Infrastructure and Domain Together - PHP and SQL within HTML
• Lack of Testing • Difficult to Maintain
Framework Fanboy Architecture
8
• Single Application Entry Point - app.php
• Some structure is present (MVC) • Still Mixing Infrastructure and Domain
- Long Controllers with SQL and Business Logic, Dummy Entities (getters and setters)
• No testing or using Web Framework • Difficult to upgrade Infrastructure
Components
9
Application Service
Any Random Action in a Web
Controller
I receive an email
10
Buenosvinos Maturity Model
11
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
Buenosvinos Maturity Model
12
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
Benefits of Hexagonal Architecture
13
• Separation of Concerns • Decoupled from the Framework • Delays Infrastructure Decisions
- Persistence Storage or Delivery Mechanism (Web, API, CLI, etc.)
• Easy to Test - Testing Application Services (or CH) - Testing Entities - Mocking between the boundaries
14
Web Controller
15
Application Service
Moving to Hexagonal Architecture
16
• Pick an action in the Web Controller - Identify Infrastructure references
(ORM, HTTP Rest Calls, Caching, etc.) - Extract Variable and to the top
• Extract Business Logic into Application Services (Copy and Paste)
• Move Infrastructure references away - ORM flush() into Repositories
• Start Unit Testing from Application Services
New Tech Policies in the Team:
1. Everything New: Hexagonal Architecture
2. Touching an Old Feature: Boy Scout Rule ("Always leave
the campground cleaner than you found it.”)
3. 100% Coverage in the Application Services
17
18
Coverage going up!
Buenosvinos Maturity Model
19
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
At this point, you can be consultant too!
20
21
“… and I want to notify the user by email, logging and sending a BI tracking” Company’s Product Owner
22
Team starts to face new issues
23
• # of Dependencies Grows • Application Service complexity Grows • More Chances to Introduce Bugs
- More developers touching the same file (Main Task and Subtasks mixed)
• More Subtasks in the same feature, Worse Performance!!
Domain Events to the rescue!
24
25
Domain Event Example
26
Firing a Domain Event
27
Domain Event Publisher Example
28
Domain Event Listener
(Elastic Example)
29
30
Domain Event Listener
(MySQL Example)
31
Domain Event Listener
(Rabbit Example)
32
Registering Domain Event
Listeners
Sync all the things!
33
TechPoliciesAdded (ok, it’s a bad joke!)
1. Subtasks of a Feature are developed in a different
Application Service and attached via Listener
2. Fire any new Event that Business may be interested
3. Let’s have a TV screen to monitor realtime Business
metrics to be proactive.34
35
Composition by Domain Events
Buenosvinos Maturity Model
36
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
37
“Hey team! Have you realised that the item page is getting quite slow?” Company’s Product Owner
Perfomance! Multiple Costly Requests (#, external, joins, etc.)
38
Async all the things!
39
Have you ever sent an email about something
that didn’t finally happen?
41
42
Problem #1: 2 Infras / 1 Tx
45
What strategies to deal with these inconsistencies can we follow?
46
• Let inconsistencies happen - The Command Handler will manage
itself (firing ArticleWasAdded, sent to RabbitMQ, but failed Database Tx)
- Feasible for most operational tasks (sending email, non-critical tracking, etc.)
• New Article Added Action and its Event persisted in the same Tx. Then Worker to move Events to Rabbit.
• Global TX (Noooooooooo!)
Problem #2: Diff(ORM) !== Diff(Events)
47
49
Max Performance!
Buenosvinos Maturity Model
50
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
Buenosvinos Maturity Model
52
Level 1: Spaghetti Level 2: Framework Fanboy Level 3: Hexagonal Architecture Level 4: Hex. + Domain Events Level 5: Stepping Stone (CQRS) Level 6: Event Sourcing + CQRS
* Tested with just 20 companies aprox.
What should be next? Getting Ready for Event Sourcing
53
• Entities are loaded from the Events already Stored
• Our Main Database is nothing but a Cache (Can we get rid of it? How much does it cost?)
• Watch Marco Pivetta’s Presentation and/or attend his Workshop on Sunday.
Thank you for your attention.