Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

A Journey from Hexagonal Architecture to Event Sourcing - SymfonyCon Cluj 2017

2,086 views

Published on

Event-based architectures such as Event Sourcing provide multiple benefits: scalability, complexity management, auditing, etc. However, let’s face it, getting there is quite hard. We lack skills, expertise and courage.

In this talk, I’m going to show you some tips and tricks to painless evolve your current architecture towards Event Sourcing, one small step at a time. We’ll start from an Hexagonal Architecture application and we’ll end up in the Event Sourcing doors. The path that we’ll follow is:

Hexagonal Architecture
Hexagonal Architecture with Domain Events
Stepping Stone Architecture (CQRS without Event Sourcing)
Event Sourcing
Talk level: Intermediate to Expert

Requirements: Basic concepts of Hexagonal Architecture (Entities, Repositories, Application Services, etc.)

Published in: Engineering

A Journey from Hexagonal Architecture to Event Sourcing - SymfonyCon Cluj 2017

  1. 1. A Journey from Hexagonal Architecture to Event Sourcing Carlos Buenosvinos (@buenosvinos) SymfonyCon Cluj 2017, November 16th, 2017
  2. 2. 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)
  3. 3. @buenosvinos
  4. 4. Domain-Driven Design in PHP Book Carlos Buenosvinos, Christian Soronellas and Keyvan Akbary https://leanpub.com/ddd-in-php
  5. 5. I want to tell you a real story about… 6
  6. 6. a Company evolving its architecture. 7
  7. 7. 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
  8. 8. 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
  9. 9. 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
  10. 10. 11 Application Service Any Random Action in a Web Controller
  11. 11. 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
  12. 12. 13 Web Controller
  13. 13. 14 Application Service
  14. 14. 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
  15. 15. 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
  16. 16. 17 Coverage going up!
  17. 17. 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
  18. 18. At this point, you can be consultant too! 19
  19. 19. 21 “… and I want to notify the user by email, logging and sending a BI tracking” Company’s Product Owner
  20. 20. 22
  21. 21. 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!!
  22. 22. Domain Events to the rescue! 24
  23. 23. 25 Domain Event Example
  24. 24. 26 Firing a Domain Event
  25. 25. 27 Domain Event Publisher Example
  26. 26. 28 Domain Event Listener (Elastic Example)
  27. 27. 29
  28. 28. 30 Domain Event Listener (MySQL Example)
  29. 29. 31 Domain Event Listener (Rabbit Example)
  30. 30. 32 Registering Domain Event Listeners
  31. 31. Sync all the things! …and buy more servers 33
  32. 32. 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
  33. 33. 35 Composition by Domain Events
  34. 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
  35. 35. 37 “Hey team! Have you realised that the item page is getting quite slow?” Company’s Product Owner
  36. 36. Perfomance! Multiple Costly Requests (#, external, joins, etc.) 38
  37. 37. Async all the things! 39
  38. 38. CQRS to the rescue! 40
  39. 39. 41
  40. 40. 42
  41. 41. Problem #1: 2 Infras / 1 Tx 45
  42. 42. 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!)
  43. 43. Problem #2: Diff(ORM) !== Diff(Events) 48
  44. 44. 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
  45. 45. 51 Max Performance!
  46. 46. 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
  47. 47. I want it all! 54
  48. 48. 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!
  49. 49. 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
  50. 50. Thank you for your attention. https://joind.in/talk/21555 @buenosvinos

×