A Journey from Hexagonal Architecture to Event Sourcing Carlos 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)
@buenosvinos 3
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.

A Journey from Hexagonal Architecture to Event Sourcing