CQRS AND EVENT SOURCING BASICS

Alexander Miertsch
Founder and CEO of prooph software GmbH
Founder and core contributor prooph components
contact@prooph.de

prooph components
CQRS and Event Sourcing packages for PHP
Supported Web Frameworks


or any other framework/codebase supporting container-interop & interop-config

Problem Space
Complex
Distributed
Chaotic
When to use CQRS & ES ?

Messages
Semantics of Messaging

Types: Command, Query, Event
Immutable DTOs
Unique names according to Domain Language
Command
Imperative Messages

Represent sender's intention
Instruct receiver to perform action
Never return data
Query
Interrogatory Messages

Ask system about it's current state
Do NOT cause stage changes
Can be cached
Domain Events
Informational Message

Named in past tense
Communicate facts that have happened
Relevant to the business
Event Storming
Deeper insights with events

Event Flow
record, publish, react

OrderPlaced
OrderPaid
OrderShipped
Change State, Then Publish
ORM - Publisher

<?php
final class OrderService
{
private $entityManager;
private $orderRepositoy;
private $eventPublisher;
public function placeOrder(string $orderId, OrderItem ...$items): void
{
$order = $this->orderRepostoy->get($orderId);
$this->entityManager->beginTransaction();
try {
$order->place($items);
$this->entityManager->commit();
} catch(\Throwable $error) {
$this->entityManager->rollBack();
throw $error;
}
$event = OrderPlaced::fromOrder($order);
$this->eventPublisher->publish($event);
}
}
Record Event, Then Publish
Event Store - Publisher

<?php
final class PlaceOrderHandler
{
private $eventStore;
private $eventPublisher;
public function handle(PlaceOrder $command): void
{
//Note: Loading/saving is normally done by event sourcing repository
$orderStream = new StreamName('order-'.$command->orderId());
$history = $this->eventStore->load($orderStream);
$order = Order::reconstituteFromHistory($history);
$newEvents = $order->place($command->items());
//Atomic operation
$this->eventStore->appendTo($orderStream, $newEvents);
$this->eventPublisher->publish($newEvents);
}
}
Event Sourcing
State is a left fold of past events

# E1 at t1: UserRegistered
userId: 1
name: John Doe
email: doe@fake.com
# E2 at t2: UsernameChanged
userId: 1
oldName: John Doe
newName: Alex
# E3 at t3: EmailChanged
userId: 1
oldEmail: doe@fake.com
newEmail: contact@prooph.de
_______________________________________________
# current state (t:now) = ((E1 + E2) + E3):
userId: 1
name: Alex
email: contact@prooph.de
version: 3
Time Travel
Debug like a boss

UserRegistered
UsernameChanged
ChangeEmailFailed
{
E1 + E2
Change Email
Temporal Queries
Use time interval as query param

UserRegistered
UsernameChanged
5 min
7 min
Who has changed username within 5 min after registration?
UserRegistered
UsernameChanged
Event Sourcing in PHP

prooph components
CQRS
SRP on system level

Gateway
Write Model
Read Model
CQRS and Event Sourcing
Double Team

Gateway
Write Model
Read Model
Event Store
Projection
Cache
Event Driven Microservices
React on Events

E1
E2
E3
E4
E5
Event Log
Document DB
Message Queue
Process Manager
Search Service
Services
subscribe
consume
CQRS in PHP

prooph components
Just Try It


Join prooph


Event Sourcing Tutorial


Thanks for listening
Questions?
PHP UG Munich 2018 CQRS and ES Basics
By prooph
PHP UG Munich 2018 CQRS and ES Basics
- 1,491