No saving state
state can be re-computed
Your object relational graph is cached state
Your DB is cached state
Your web pages are cached state
Events are in a sequence
Events are immutable
Cache forever
Reconstructing state is fast
Writes are also sequential
append-only event store
Less race conditions
No data loss, ever.
class ATraditionalCounter
{
private $count = 0;
public function increment()
{
$this->count += 1;
}
public function getCurrentCount() : int
{
return $this->count;
}
}
There is absolutely nothing wrong with ATraditionalCounter
But what if we need any of the following?
ATraditionalCounter#getWhenTheCounterWasIncremented()
ATraditionalCounter#whoIncrementedTheCounter()
ATraditionalCounter#whenWasTheCounterCreated()
ATraditionalCounter#whenWasTheCounterLastUpdated()
All dumb questions when nobody cares...
... big trouble for accounting, invoicing, banking, geolocation, analytics.
class AnEventSourcedCounter
{
private $events;
public function increment()
{
$this->events = new CounterWasIncremented(1, new \DateTime('now'), whoami());
}
public function getCurrentCount() : int
{
return count(array_filter(
function ($event) {
return $event instanceof CounterWasIncremented;
},
$this->events
));
}
}
No frameworks
No magic
Just HTTP and PHP
AJAX Polling (for simplicity)
There is no point in building event-sourced apps for CRUD
I chose Bowling for that.