a journey from hexagonal architecture to event sourcing - symfonycon cluj 2017
TRANSCRIPT
A Journey from Hexagonal Architecture to Event SourcingCarlos Buenosvinos (@buenosvinos)
SymfonyCon Cluj 2017, November 16th, 2017
Who am I? Carlos Buenosvinos
• VP of Technology @ XING • Consultant as a Hobby • +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)
Domain-Driven Design in PHP Book Carlos Buenosvinos, Christian Soronellas and Keyvan Akbary
https://leanpub.com/ddd-in-php
Buenosvinos Maturity Model
8
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
Spaghetti Architecture
9
• 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
10
• 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
Benefits of Hexagonal Architecture
12
• Separation of Concerns • Promotes decoupling 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
Moving to Hexagonal Architecture
15
1. Pick an action in the Web Controller Identify Infrastructure references (ORM, HTTP Rest Calls, Caching, etc.) Extract Variable and move them to the top 2. Extract Business Logic into Application
Services (Extract Class/Copy & Paste) 3. Move Infrastructure references away ORM flush() into add() in Repositories 4. 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
16
Buenosvinos Maturity Model
18
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
21
“… and I want to notify the user by email, logging and sending a BI tracking” Company’s Product Owner
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!!
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
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
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!)
Changes from Hexagonal Architecture to Stepping Stone (CQRS)
50
• Entity state is still fetched from the database (read) - 3rd Normal Form - Now database is a cache
• Entities hold events triggered - Use a trait or a base class
• Repositories now only persist a bunch of events to your queue (no updates) - You will only send messages to
RabbitMQ or your queue
Buenosvinos Maturity Model
53
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
What’s remaining to get to Event Sourcing?
55
• Entities state is not loaded from the database, is reconstituted from the Events from the Event Store.
• Migrate Entities one at a time.
• Enjoy!
Buenosvinos Maturity Model
56
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