a journey from hexagonal architecture to event sourcing - symfonycon cluj 2017

57
A Journey from Hexagonal Architecture to Event Sourcing Carlos Buenosvinos (@buenosvinos) SymfonyCon Cluj 2017, November 16th, 2017

Upload: carlos-buenosvinos

Post on 21-Jan-2018

920 views

Category:

Engineering


0 download

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)

@buenosvinos

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…

6

a Company evolving its architecture.

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

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

11

Application Service

Any Random Action in a Web

Controller

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

13

Web Controller

14

Application Service

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

17

Coverage going up!

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

At this point, you can be consultant too!

19

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!

…and buy more servers

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

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

CQRS to the rescue!

40

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)

48

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

51

Max Performance!

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

I want it all!54

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

Thank you for your attention.

https://joind.in/talk/21555 @buenosvinos