SlideShare a Scribd company logo
1 of 74
Download to read offline
IntroductiontoCQRS
andEventSourcingSamuel ROZE (@samuelroze)
Theheartofsoftwareisitsability
tosolvedomain-related
problemsforitsuser
— Eric Evans
EventStorming
EventSourcing
Ourdomain
1. Create a "deployment"
2. Start a deployment
3. Realtime status of our deployment
Ourmodelisthis...
Anentity
+------------------+
| Deployment |
+------------------+
|- uuid: Uuid |
|- sha1: string |
|- status: string |
|- startedBy: User |
+------------------+
Whatwecouldhavedone
ADoctrinemappingand..atable!
+-------------------+
| deployment |
+-------------------+
| uuid VARCHAR |
| status VARCHAR |
| sha1 VARCHAR |
| startedBy VARCHAR |
+-------------------+
Anotherapproach
Asetofeventsasthereference!
+-------------------------------------+
|DeploymentCreated |DeploymentStarted |
| uuid: [...] | uuid: [...] | ...
| datetime: [...] | datetime: [...] |
| sha1: [...] | startedBy: [...] |
+------------------+------------------+
Whyusingevents?
1. Closer to the business language
2. Keep the information about what happened
3. Easy to spread the logic across services
4. No coupling between domain and storage
5. Append-only it's a LOT easier to scale
Let'sgetstarted!
Scenario: A deployment need to have a valid SHA-1
When I create a deployment for "123"
Then the deployment should not be valid
Scenario: Deployment for a valid SHA-1
When I create a deployment for "921103d"
Then a deployment should be created
@When I create a deployment for :sha1
public function iCreateADeploymentFor(string $sha1)
{
try {
$this->deployment = Deployment::create(
Uuid::uuid4(),
$sha1
);
} catch (Throwable $e) {
$this->exception = $e;
}
}
@Then the deployment should not be valid
public function theDeploymentShouldNotBeValid()
{
if (!$this->exception instanceof InvalidArgumentException) {
throw new RuntimeException(
'The exception found, if any, is not matching'
);
}
}
@Then a deployment should be created
public function aDeploymentShouldBeCreated()
{
$events = $this->deployment->raisedEvents();
$matchingEvents = array_filter($events, function(DeploymentEvent $event) {
return $event instanceof DeploymentCreated;
});
if (count($matchingEvents) === 0) {
throw new RuntimeException('No deployment created found');
}
}
Erm...
$ bin/behat -fprogress
FFFF
2 scenarios (0 passed)
4 steps (0 passed)
0m0.12s (40.89Mb)
Anevent
interface DeploymentEvent
{
public function getDeploymentUuid() : UuidInterface;
public function getDateTime(): DateTimeInterface;
}
'DeploymentCreated'event
final class DeploymentCreated implements DeploymentEvent
{
public function __construct(UuidInterface $uuid, string $sha1)
{ /* .. */ }
public function getDeploymentUuid() : UuidInterface
{
return $this->uuid;
}
public function getSha1() : string
{
return $this->sha1;
}
}
Eventcapability
trait EventsCapability
{
private $events = [];
protected function raise(DeploymentEvent $event)
{
$this->events[] = $event;
}
public function raisedEvents() : array
{
return $this->events;
}
}
Theaggregate
final class Deployment
{
use EventsCapability;
private function __construct()
{}
}
Creatingtheobjectfromevents
final class Deployment
{
// ...
public static function fromEvents(array $events)
{
$deployment = new self();
foreach ($events as $event) {
$deployment->apply($event);
}
return $deployment;
}
}
Buildingtheobjectstate
final class Deployment
{
private $uuid;
// ...
private function apply(DeploymentEvent $event)
{
if ($event instanceof DeploymentCreated) {
$this->uuid = $event->getDeploymentUuid();
}
}
}
Create...fromthebeginning!
final class Deployment
{
// ...
public static function create(Uuid $uuid, string $sha1)
{
if (strlen($sha1) < 7) {
throw new InvalidArgumentException('It is not a valid SHA-1');
}
$createdEvent = new DeploymentCreated($uuid, $sha1);
$deployment = self::fromEvents([$createdEvent]);
$deployment->raise($createdEvent);
return $deployment;
}
}
Wourah!
$ bin/behat -fprogress
....
2 scenarios (2 passed)
4 steps (4 passed)
0m0.12s (40.89Mb)
Startingadeployment!
Scenario: A successfully created deployment can be started
Given a deployment was created
When I start the deployment
Then the deployment should be started
Scenario: A deployment can be started only once
Given a deployment was created and started
When I start the deployment
Then I should be told that the deployment has already started
@Given a deployment was created and started
public function aDeploymentWasCreatedAndStarted()
{
$uuid = Uuid::uuid4();
$this->deployment = Deployment::fromEvents([
new DeploymentCreated($uuid, '921103d'),
new DeploymentStarted($uuid),
]);
}
@When I start the deployment
public function iStartTheDeployment()
{
try {
$this->deployment->start();
} catch (Throwable $e) {
$this->exception = $e;
}
}
'start'ingadeployment
final class Deployment
{
private $uuid;
private $started = false;
// ...
public function start()
{
if ($this->started) {
throw new RuntimeException('Deployment already started');
}
$this->raise(new DeploymentStarted($this->uuid));
}
}
Keepingtraceofthestatus
final class Deployment
{
private $started = false;
// ...
public function apply(DeploymentEvent $event)
{
// ...
if ($event instanceof DeploymentStarted) {
$this->started = true;
}
}
}
That'stoofast...
$ bin/behat -fprogress
.........
4 scenarios (4 passed)
10 steps (10 passed)
0m0.31s (41.22Mb)
Wearedone!
...withourdomain
Repositories&Persistence
EventStore
interface EventStore
{
public function findByDeploymentUuid(UuidInterface $uuid) : array;
public function add(DeploymentEvent $event);
}
Implementation detail: InMemory / Doctrine /
Redis / GetEventStore / ...
Ourrepositorycontract
interface DeploymentRepository
{
public function find(UuidInterface $uuid) : Deployment;
}
Theevent-basedimplementation
final class EventBasedDeploymentRepository implements DeploymentRepository
{
public function __construct(EventStore $eventStore)
{ /** .. **/ }
public function find(UuidInterface $uuid) : Deployment
{
return Deployment::fromEvents(
$this->eventStore->findByDeploymentUuid($uuid)
);
}
}
CQRS?
Projections!
The"readmodel"
· Creates a read-optimized view of our model
· As many projection as you want
· Any kind of backend (database, API, queue, ...)
final class DeploymentFirebaseProjector
{
public function __construct(
DeploymentRepository $repository,
FirebaseStorage $storage
) { /* ... */ }
public function notify(DeploymentEvent $event)
{
$uuid = $event->getDeploymentUuid();
$deployment = $this->repository->find($uuid);
$this->storage->store('deployments/'.$uuid, [
'started' => $deployment->isStarted(),
]);
}
}
We'vedoneit!
1. Create a "deployment"
2. Start a deployment
3. Realtime status of our deployment
Thankyou!
@samuelroze
continuouspipe.io
https://joind.in/talk/03af6
SimpleBus
· Written by Matthias Noback
http://simplebus.github.io/SymfonyBridge/
# app/config/config.yml
event_bus:
logging: ~
command_bus:
logging: ~
final class DeploymentController
{
private $eventBus;
public function __construct(MessageBus $eventBus)
{ /* ... */ }
public function createAction(Request $request)
{
$deployment = Deployment::create(
Uuid::uuid4(),
$request->request->get('sha1')
);
foreach ($deployment->raisedEvents() as $event) {
$this->eventBus->handle($event);
}
return new Response(Response::HTTP_CREATED);
}
}
final class DeploymentController
{
private $commandBus;
public function __construct(MessageBus $commandBus)
{ /* ... */ }
public function createAction(Request $request)
{
$uuid = Uuid::uuid4();
$this->commandBus->handle(new CreateDeployment(
$uuid,
$request->request->get('sha1')
));
return new Response(Response::HTTP_CREATED);
}
}
final class CreateDeploymentHandler
{
private $eventBus;
public function __construct(MessageBus $eventBus)
{ /* ... */ }
public function handle(CreateDeployment $command)
{
$deployment = Deployment::create(
$command->getUuid(),
$command->getSha1()
);
foreach ($deployment->raisedEvents() as $event) {
$this->eventBus->handle($event);
}
}
}
Theplumbing
<service id="app.controller.deployment"
class="AppBundleControllerDeploymentController">
<argument type="service" id="command_bus" />
</service>
<service id="app.handler.create_deployment"
class="AppDeploymentHandlerCreateDeploymentHandler">
<argument type="service" id="event_bus" />
<tag name="command_handler" handles="AppCommandCreateDeployment" />
</service>
Whatdowehaverightnow?
1. Send a command from an HTTP API
2. The command handler talks to our domain
3. Domain raise an event
4. The event is dispatched to the event bus
Storingourevents
final class DeploymentEventStoreMiddleware implements MessageBusMiddleware
{
private $eventStore;
public function __construct(EventStore $eventStore)
{
$this->eventStore = $eventStore;
}
public function handle($message, callable $next)
{
if ($message instanceof DeploymentEvent) {
$this->eventStore->add($message);
}
$next($message);
}
}
We<3XML
<service id="app.event_bus.middleware.store_events"
class="AppEventBusMiddlewareStoreEvents">
<argument type="service" id="event_store" />
<tag name="event_bus_middleware" />
</service>
Oureventsarestored!
...sowecangetour
Deploymentfromthe
repository
Let'sstartourdeployment!
final class StartDeploymentWhenCreated
{
private $commandBus;
public function __construct(MessageBus $commandBus)
{ /* ... */ }
public function notify(DeploymentCreated $event)
{
// There will be conditions here...
$this->commandBus->handle(new StartDeployment(
$event->getDeploymentUuid()
));
}
}
Thehandler
final class StartDeploymentHandler
{
public function __construct(DeploymentRepository $repository, MessageBus $eventBus)
{ /* ... */ }
public function handle(StartDeployment $command)
{
$deployment = $this->repository->find($command->getDeploymentUuid());
$deployment->start();
foreach ($deployment->raisedEvents() as $event) {
$this->eventBus->handle($event);
}
}
}
Theplumbing
<service id="app.deployment.auto_start.starts_when_created"
class="AppDeploymentAutoStartStartsWhenCreated">
<argument type="service" id="command_bus" />
<tag name="event_subscriber"
subscribes_to="AppEventDeploymentCreated" />
</service>
<service id="app.deployment.handler.start_deployment"
class="AppDeploymentHandlerStartDeploymentHandler">
<argument type="service" id="app.deployment_repository" />
<argument type="service" id="event_bus" />
<tag name="command_handler" handles="AppCommandStartDeployment" />
</service>
Whathappened?
[...]
4. A dispatched DeploymentCreated event
5. A listener created a StartDeployment
command
6. The command handler called the start
method on the Deployment
7. The domain validated and raised a
DeploymentStarted event
8. The DeploymentStarted was dispatched on
You'llgofurther...
final class Deployment
{
// ...
public function finishedBuild(Build $build)
{
if ($build->isFailure()) {
return $this->raise(new DeploymentFailed($this->uuid));
}
$this->builtImages[] = $build->getImage();
if (count($this->builtImages) == count($this->images)) {
$this->raise(new DeploymentSuccessful($this->uuid));
}
}
}
Dependencies...thewrongway
final class Deployment
{
private $notifier;
public function __construct(NotifierInterface $notifier)
{ /* .. */ }
public function notify()
{
$this->notifier->notify($this);
}
}
Dependencies...therightway
final class Deployment
{
public function notify(NotifierInterface $notifier)
{
$notifier->notify($this);
}
}
Testing!(layers)
1. Use your domain objects
2. Create commands and read your event store
3. Uses your API and projections
Whatwejustachieved
1. Incoming HTTP requests
2. Commands to the command bus
3. Handlers talk to your domain
4. Domain produces events
5. Events are stored and dispatched
6. Projections built for fast query
Thankyou!
@samuelroze
continuouspipe.io
https://joind.in/talk/03af6

More Related Content

What's hot

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For BeginnersJonathan Wage
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design PatternsHugo Hamon
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistenceHugo Hamon
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixturesBill Chang
 
Love and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayLove and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayKris Wallsmith
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonKris Wallsmith
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Konstantin Kudryashov
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Colin O'Dell
 
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integrationSylius and Api Platform The story of integration
Sylius and Api Platform The story of integrationŁukasz Chruściel
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony AppsKris Wallsmith
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsŁukasz Chruściel
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuerysergioafp
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 

What's hot (20)

Doctrine For Beginners
Doctrine For BeginnersDoctrine For Beginners
Doctrine For Beginners
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Database Design Patterns
Database Design PatternsDatabase Design Patterns
Database Design Patterns
 
The History of PHPersistence
The History of PHPersistenceThe History of PHPersistence
The History of PHPersistence
 
Doctrine fixtures
Doctrine fixturesDoctrine fixtures
Doctrine fixtures
 
Love and Loss: A Symfony Security Play
Love and Loss: A Symfony Security PlayLove and Loss: A Symfony Security Play
Love and Loss: A Symfony Security Play
 
Min-Maxing Software Costs
Min-Maxing Software CostsMin-Maxing Software Costs
Min-Maxing Software Costs
 
Matters of State
Matters of StateMatters of State
Matters of State
 
How kris-writes-symfony-apps-london
How kris-writes-symfony-apps-londonHow kris-writes-symfony-apps-london
How kris-writes-symfony-apps-london
 
Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015Min-Maxing Software Costs - Laracon EU 2015
Min-Maxing Software Costs - Laracon EU 2015
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Symfony2 your way
Symfony2   your waySymfony2   your way
Symfony2 your way
 
Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016Hacking Your Way To Better Security - Dutch PHP Conference 2016
Hacking Your Way To Better Security - Dutch PHP Conference 2016
 
Sylius and Api Platform The story of integration
Sylius and Api Platform The story of integrationSylius and Api Platform The story of integration
Sylius and Api Platform The story of integration
 
How Kris Writes Symfony Apps
How Kris Writes Symfony AppsHow Kris Writes Symfony Apps
How Kris Writes Symfony Apps
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
Bacbkone js
Bacbkone jsBacbkone js
Bacbkone js
 
Mocking Demystified
Mocking DemystifiedMocking Demystified
Mocking Demystified
 
Advanced jQuery
Advanced jQueryAdvanced jQuery
Advanced jQuery
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 

Viewers also liked

Utiliser Webpack dans une application Symfony
Utiliser Webpack dans une application SymfonyUtiliser Webpack dans une application Symfony
Utiliser Webpack dans une application SymfonyAlain Hippolyte
 
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsJWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsAndré Tapia
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiJérémy Derussé
 
Symfony 2 : Performances et Optimisations
Symfony 2 : Performances et OptimisationsSymfony 2 : Performances et Optimisations
Symfony 2 : Performances et OptimisationsLes-Tilleuls.coop
 
Creating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkCreating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkLes-Tilleuls.coop
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheLeslie Samuel
 
Industrializing eZ publish project development
Industrializing eZ publish project developmentIndustrializing eZ publish project development
Industrializing eZ publish project developmentJérôme Vieilledent
 
IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017Matheus Marabesi
 
Essay about event driven architecture
Essay about event driven architectureEssay about event driven architecture
Essay about event driven architecturePaulo Victor Gomes
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5julien pauli
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?Ravi Raj
 
Json web token api authorization
Json web token api authorizationJson web token api authorization
Json web token api authorizationGiulio De Donato
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in phpLeonardo Proietti
 
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...FrenchWeb.fr
 

Viewers also liked (18)

Utiliser Webpack dans une application Symfony
Utiliser Webpack dans une application SymfonyUtiliser Webpack dans une application Symfony
Utiliser Webpack dans une application Symfony
 
JWT - Sécurisez vos APIs
JWT - Sécurisez vos APIsJWT - Sécurisez vos APIs
JWT - Sécurisez vos APIs
 
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry PiGrâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
Grâce aux tags Varnish, j'ai switché ma prod sur Raspberry Pi
 
Symfony 2 : Performances et Optimisations
Symfony 2 : Performances et OptimisationsSymfony 2 : Performances et Optimisations
Symfony 2 : Performances et Optimisations
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Creating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform frameworkCreating hypermedia APIs in a few minutes using the API Platform framework
Creating hypermedia APIs in a few minutes using the API Platform framework
 
How to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your NicheHow to Become a Thought Leader in Your Niche
How to Become a Thought Leader in Your Niche
 
Industrializing eZ publish project development
Industrializing eZ publish project developmentIndustrializing eZ publish project development
Industrializing eZ publish project development
 
eZ Publish 5 in depth inspection
eZ Publish 5 in depth inspectioneZ Publish 5 in depth inspection
eZ Publish 5 in depth inspection
 
Symfony and eZ Publish
Symfony and eZ PublishSymfony and eZ Publish
Symfony and eZ Publish
 
IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017IoT powered by PHP and streams - PHPExperience2017
IoT powered by PHP and streams - PHPExperience2017
 
Essay about event driven architecture
Essay about event driven architectureEssay about event driven architecture
Essay about event driven architecture
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?
 
Json web token api authorization
Json web token api authorizationJson web token api authorization
Json web token api authorization
 
PHP7 is coming
PHP7 is comingPHP7 is coming
PHP7 is coming
 
Clean architecture with ddd layering in php
Clean architecture with ddd layering in phpClean architecture with ddd layering in php
Clean architecture with ddd layering in php
 
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...
[SEN#7] Le classement des Entreprises de Service du Numérique (ex-SSII) qui r...
 

Similar to Introduction to CQRS and Event Sourcing

Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesLindsay Holmwood
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Librariesjeresig
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ EtsyNishan Subedi
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developersPavel Lahoda
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon Berlin
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleThierry Wasylczenko
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015Fernando Daciuk
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinNida Ismail Shah
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScriptAndrew Dupont
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every dayVadym Khondar
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...DroidConTLV
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Ryan Weaver
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsBastian Feder
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic ComponentsMateusz Tymek
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 

Similar to Introduction to CQRS and Event Sourcing (20)

Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Burn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websitesBurn down the silos! Helping dev and ops gel on high availability websites
Burn down the silos! Helping dev and ops gel on high availability websites
 
Secrets of JavaScript Libraries
Secrets of JavaScript LibrariesSecrets of JavaScript Libraries
Secrets of JavaScript Libraries
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
Virtual Madness @ Etsy
Virtual Madness @ EtsyVirtual Madness @ Etsy
Virtual Madness @ Etsy
 
Improving android experience for both users and developers
Improving android experience for both users and developersImproving android experience for both users and developers
Improving android experience for both users and developers
 
Droidcon2013 android experience lahoda
Droidcon2013 android experience lahodaDroidcon2013 android experience lahoda
Droidcon2013 android experience lahoda
 
Construire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradleConstruire une application JavaFX 8 avec gradle
Construire une application JavaFX 8 avec gradle
 
WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015WordPress Realtime - WordCamp São Paulo 2015
WordPress Realtime - WordCamp São Paulo 2015
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
The IoC Hydra
The IoC HydraThe IoC Hydra
The IoC Hydra
 
Writing Maintainable JavaScript
Writing Maintainable JavaScriptWriting Maintainable JavaScript
Writing Maintainable JavaScript
 
Separation of concerns - DPC12
Separation of concerns - DPC12Separation of concerns - DPC12
Separation of concerns - DPC12
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
Tricks to Making a Realtime SurfaceView Actually Perform in Realtime - Maarte...
 
Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)Symfony: Your Next Microframework (SymfonyCon 2015)
Symfony: Your Next Microframework (SymfonyCon 2015)
 
PhpUnit - The most unknown Parts
PhpUnit - The most unknown PartsPhpUnit - The most unknown Parts
PhpUnit - The most unknown Parts
 
Zend Framework 2 - Basic Components
Zend Framework 2  - Basic ComponentsZend Framework 2  - Basic Components
Zend Framework 2 - Basic Components
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 

More from Samuel ROZE

Event streaming: what will go wrong? (Symfony World 2020)
Event streaming: what will go wrong? (Symfony World 2020)Event streaming: what will go wrong? (Symfony World 2020)
Event streaming: what will go wrong? (Symfony World 2020)Samuel ROZE
 
Living documentation
Living documentationLiving documentation
Living documentationSamuel ROZE
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Samuel ROZE
 
Micro services may not be the best idea
Micro services may not be the best ideaMicro services may not be the best idea
Micro services may not be the best ideaSamuel ROZE
 
Take care of our micro services
Take care of our micro servicesTake care of our micro services
Take care of our micro servicesSamuel ROZE
 
(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et ToleranceSamuel ROZE
 
Using continuouspipe to speed up our workflows
Using continuouspipe to speed up our workflowsUsing continuouspipe to speed up our workflows
Using continuouspipe to speed up our workflowsSamuel ROZE
 
Behat c'est plus que ça | Behat is more than that
Behat c'est plus que ça | Behat is more than thatBehat c'est plus que ça | Behat is more than that
Behat c'est plus que ça | Behat is more than thatSamuel ROZE
 
Docker orchestration with Kubernetes
Docker orchestration with KubernetesDocker orchestration with Kubernetes
Docker orchestration with KubernetesSamuel ROZE
 
Symfony et serialization avec JMS serializer
Symfony et serialization avec JMS serializer Symfony et serialization avec JMS serializer
Symfony et serialization avec JMS serializer Samuel ROZE
 

More from Samuel ROZE (10)

Event streaming: what will go wrong? (Symfony World 2020)
Event streaming: what will go wrong? (Symfony World 2020)Event streaming: what will go wrong? (Symfony World 2020)
Event streaming: what will go wrong? (Symfony World 2020)
 
Living documentation
Living documentationLiving documentation
Living documentation
 
Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)Symfony Messenger (Symfony Live San Francisco)
Symfony Messenger (Symfony Live San Francisco)
 
Micro services may not be the best idea
Micro services may not be the best ideaMicro services may not be the best idea
Micro services may not be the best idea
 
Take care of our micro services
Take care of our micro servicesTake care of our micro services
Take care of our micro services
 
(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance(micro)services avec Symfony et Tolerance
(micro)services avec Symfony et Tolerance
 
Using continuouspipe to speed up our workflows
Using continuouspipe to speed up our workflowsUsing continuouspipe to speed up our workflows
Using continuouspipe to speed up our workflows
 
Behat c'est plus que ça | Behat is more than that
Behat c'est plus que ça | Behat is more than thatBehat c'est plus que ça | Behat is more than that
Behat c'est plus que ça | Behat is more than that
 
Docker orchestration with Kubernetes
Docker orchestration with KubernetesDocker orchestration with Kubernetes
Docker orchestration with Kubernetes
 
Symfony et serialization avec JMS serializer
Symfony et serialization avec JMS serializer Symfony et serialization avec JMS serializer
Symfony et serialization avec JMS serializer
 

Recently uploaded

Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)dollysharma2066
 
Class 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm SystemClass 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm Systemirfanmechengr
 
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerAnamika Sarkar
 
Piping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringPiping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringJuanCarlosMorales19600
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile servicerehmti665
 
Transport layer issues and challenges - Guide
Transport layer issues and challenges - GuideTransport layer issues and challenges - Guide
Transport layer issues and challenges - GuideGOPINATHS437943
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncssuser2ae721
 
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEINFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEroselinkalist12
 
lifi-technology with integration of IOT.pptx
lifi-technology with integration of IOT.pptxlifi-technology with integration of IOT.pptx
lifi-technology with integration of IOT.pptxsomshekarkn64
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.eptoze12
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfROCENODodongVILLACER
 
An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...Chandu841456
 
US Department of Education FAFSA Week of Action
US Department of Education FAFSA Week of ActionUS Department of Education FAFSA Week of Action
US Department of Education FAFSA Week of ActionMebane Rash
 
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024hassan khalil
 
Arduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptArduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptSAURABHKUMAR892774
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the weldingMuhammadUzairLiaqat
 
Correctly Loading Incremental Data at Scale
Correctly Loading Incremental Data at ScaleCorrectly Loading Incremental Data at Scale
Correctly Loading Incremental Data at ScaleAlluxio, Inc.
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionDr.Costas Sachpazis
 

Recently uploaded (20)

Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
Call Us ≽ 8377877756 ≼ Call Girls In Shastri Nagar (Delhi)
 
Class 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm SystemClass 1 | NFPA 72 | Overview Fire Alarm System
Class 1 | NFPA 72 | Overview Fire Alarm System
 
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube ExchangerStudy on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
Study on Air-Water & Water-Water Heat Exchange in a Finned Tube Exchanger
 
Piping Basic stress analysis by engineering
Piping Basic stress analysis by engineeringPiping Basic stress analysis by engineering
Piping Basic stress analysis by engineering
 
Call Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile serviceCall Girls Delhi {Jodhpur} 9711199012 high profile service
Call Girls Delhi {Jodhpur} 9711199012 high profile service
 
Transport layer issues and challenges - Guide
Transport layer issues and challenges - GuideTransport layer issues and challenges - Guide
Transport layer issues and challenges - Guide
 
Design and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdfDesign and analysis of solar grass cutter.pdf
Design and analysis of solar grass cutter.pdf
 
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsyncWhy does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
Why does (not) Kafka need fsync: Eliminating tail latency spikes caused by fsync
 
POWER SYSTEMS-1 Complete notes examples
POWER SYSTEMS-1 Complete notes  examplesPOWER SYSTEMS-1 Complete notes  examples
POWER SYSTEMS-1 Complete notes examples
 
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETEINFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
INFLUENCE OF NANOSILICA ON THE PROPERTIES OF CONCRETE
 
lifi-technology with integration of IOT.pptx
lifi-technology with integration of IOT.pptxlifi-technology with integration of IOT.pptx
lifi-technology with integration of IOT.pptx
 
Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.Oxy acetylene welding presentation note.
Oxy acetylene welding presentation note.
 
Risk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdfRisk Assessment For Installation of Drainage Pipes.pdf
Risk Assessment For Installation of Drainage Pipes.pdf
 
An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...An experimental study in using natural admixture as an alternative for chemic...
An experimental study in using natural admixture as an alternative for chemic...
 
US Department of Education FAFSA Week of Action
US Department of Education FAFSA Week of ActionUS Department of Education FAFSA Week of Action
US Department of Education FAFSA Week of Action
 
Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024Architect Hassan Khalil Portfolio for 2024
Architect Hassan Khalil Portfolio for 2024
 
Arduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.pptArduino_CSE ece ppt for working and principal of arduino.ppt
Arduino_CSE ece ppt for working and principal of arduino.ppt
 
welding defects observed during the welding
welding defects observed during the weldingwelding defects observed during the welding
welding defects observed during the welding
 
Correctly Loading Incremental Data at Scale
Correctly Loading Incremental Data at ScaleCorrectly Loading Incremental Data at Scale
Correctly Loading Incremental Data at Scale
 
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective IntroductionSachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
Sachpazis Costas: Geotechnical Engineering: A student's Perspective Introduction
 

Introduction to CQRS and Event Sourcing