Introduction to Event Sourcing and CQRS

Post on 05-Jul-2015

372 Views

Category:

Technology

4 Downloads

Preview:

Click to see full reader

DESCRIPTION

Event sourcing is a pattern for modelling your application’s business logic. It states that all changes to application state should be defined and stored as a sequence of events. The idea of recording events for information storage is nothing new. It has been used for decades in finance, healthcare, and other fields. A few years ago it was rediscovered in software design and its advantages are many: - Suitable for building scalable, highly concurrent, distributed systems. - The stored events give you the true history of a system. This audit is required by law in some industries. - The system’s state can be reversed to any point in the past for retroactive debugging and data analysis. - Gives freedom to refactor your business logic, thus allows much better response to new requirements. - The required infrastructure is simple - no monstrous databases are involved. The focus of my talk will be the Event Sourcing pattern, but I’ll also briefly describe CQRS - an architecture that goes hand in hand with Event Sourcing.

Transcript

Introduction to Event Sourcing … and CQRS

Vladik KhononovSolutions Architect at Plexop

http://il.linkedin.com/in/vladikkhononov/

vladikk vladikkhttp://vladikk.com

Introduction to Event Sourcing… and CQRS

Domain Driven Design?

IntroductionHow we are used to do things

PresentationDALBusiness Logic

Domain Model

– www.dictionary.com

Model: A simplified representation of a system or phenomenon.

– www.wikipedia.org

מודל: ייצוג תאורטי של מערכת מורכבת, שמטרתו לחקות את המערכת בהיבטים מהותיים. המודל

אינו מתאר כל תופעה במערכת, אלא מתייחס להיבטים מוגדרים ומצומצמים שלה. המודל

מבוסס על קירוב של המציאות בדרך של הפשטה, איחוד ישויות והתעלמות מגורמים שהשפעתם

אינה מהותית.

User Interface StorageDomain

Model

Domain Model

Good Domain Model• Not too much

• Not too less

• Sweet spot

• The information we need

• The information we might need

Why domain models fail

• We absolutely suck at predicting the future

• No single model can suit all the use cases (e.g.: transactional processing, business intelligence, search)

• Model transformations are painful

Case Study: Customers Management

• A customer has customer id number and a name • A customer has contact information: email, phone

number • A customer can be in on of the following states:

New, CallLater, Converted, NotInterested • A seller has seller id number, name and password • The selling home page contains a list of the

customers in the following statuses: • New • CallLater (when scheduled call date is met)

• Seller chooses a customer to call from the home page

• Seller can change the customer’s status to “Converted”, “Not Interested”

• Seller can schedule a future call by setting the future call date. The Customer’s status will change to “CallLater”

• Seller can change name, email, and phone number

enum Status { New, CallLater, Converted, NotInterested }

class Customer { int Id; string Name; Status Status; DateTime? ScheduledCall; string Email; string PhoneNumber;}

CREATE TABLE Customers ( ID INTEGER, Name CHAR(40), Email CHAR(40), PhoneNumber CHAR(40), Status INTEGER, ScheduledCall DATETIME, PRIMARY KEY (ID))

class Seller { int Id; string Name; string Password;}

CREATE TABLE Sellers ( ID INTEGER, Name CHAR(40), Password CHAR(40) PRIMARY KEY (ID))

• Seller can find customers by name, email, and/or phone number in the search page

• The customers should be found by the current and the past values

• If no new customers are available on the home page, it should display customers in the NotInterested status, if it was set more than a 30 days ago

• Analysts should be able to review status changes history for each customer - change date and the new status

class Seller { int Id; string Name; string Password;}

CREATE TABLE Sellers ( ID INTEGER, Name CHAR(40), Password CHAR(40) PRIMARY KEY (ID))

enum Status { New, CallLater, Converted, NotInterested }

class Customer { int Id; string Name; Status Status; DateTime? ScheduledCall; string Email; string PhoneNumber;}

CREATE TABLE Customers ( ID INTEGER, Name CHAR(40), Email CHAR(40), PhoneNumber CHAR(40), Status INTEGER, ScheduledCall DATETIME, PRIMARY KEY (ID))

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 04-2342343 New

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 04-2342343 CallLater 27/10/2014

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 08-9876653 CallLater 27/10/2014

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 08-9876653 Converted

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 08-9876653 Converted

Event SourcingCapture all changes to an application

state as a sequence of events ~ Martin Fowler

class StatusChanged : IEvent { Status NewStatus; DateTime CreatedOn; int CreatedBy; }

class FutureCallScheduled : IEvent { DateTime ScheduledCallTime; DateTime CreatedOn; int CreatedBy; }

class ContactDetailsWereUpdated : IEvent { string NewName; string NewEmail; string NewPhone; DateTime CreatedOn; int CreatedBy; }

class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall;

List<IEvent> Events; …

void Apply(StatusChanged e) { Status = e.NewStatus;Events.Add(e);

} …. ….}

class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall;

List<IEvent> Events; … …

void Apply(FutureCallScheduled e) { ScheduledCall = e.ScheduledCallTime;Events.Add(e);

} …}

class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall;

List<IEvent> Events; … … …

void Apply(ContactDetailsWereUpdated e) { Name = e.NewName;Email = e.NewEmail;PhoneNumber = e.NewPhoneNumber;Events.Add(e);

} }

Id Name Email Phone number Status Scheduled Call

10 John john@gmail.com 08-9876653 Converted

1. new StatusChanged(Status.CallLater)

2. new FutureCallScheduled(’27/10/2014’)

3. new ContactDetailsWereUpdated( NewPhoneNumber=’08-9876653’)

4. new StatusChanged(Status.Converted)

Event Storage

Entity Id + New events

Entity IdEvent1,Event2,Event3,

….

class CustomerSearchModel { int Id; List<string> Names; List<string> Emails; List<string> PhoneNumbers; Status Status; DateTime? ScheduledCall; … … …

void Apply(ContactDetailsWereUpdated e) { Names.Add(e.NewName);Emails.Add(e.NewEmail);PhoneNumbers.Add(e.NewPhoneNumber);

} }

class CustomerAnalysisModel { int Id; string Name; string Email; string PhoneNumber;

List<StatusChange> StatusChanges; DateTime? ScheduledCall; …

void Apply(StatusChanged e) { StatusChanges.Add(

new StatusChange(e.CreatedOn, e.NewStatus));

} …. ….}

class Customer { int Id; string Name; string Email; string PhoneNumber; Status Status; DateTime? ScheduledCall; List<IEvent> Events;}

class CustomerSearchModel { int Id; List<string> Names;

List<string> Emails;List<string> PhoneNumbers;

Status Status; DateTime? ScheduledCall;}

class CustomerAnalysisModel { int Id; string Name; string Email; string PhoneNumber;

List<StatusChange> StatusChanges; DateTime? ScheduledCall; }

Good Domain Model✓ Not too much

✓ Not too less

✓ Sweet spot

✓ The information we need

✓ The information we might need

Why domain models fail

✓ We absolutely suck at predicting the future

✓ No single model can suit all the use cases (e.g.: transactional processing, business intelligence, search)

✓ Model transformations are painful

Event Storage

Entity Id + New events

Entity IdEvent1,Event2,Event3,

….

CQRSCommand Query Responsibility Segregation

Laye

red

Arch

itect

ure

Step

1

Step

2

Step

3

CQ

RS

• Event based models

• Effective modeling

• No future predicting required

• Time machine

• Retroactive debugging

• Infrastructural freedom

• Infinite scalability

• Easy to scale writes

• Easy to scale reads

Conclusions

Before you try this at home

• Read “Implementing Domain Driven Design” by Vaughn Vernon

• Read “Domain Driven Design” by Eric Evans

• Follow Greg Young

• Read DDD/CQRS on Google Groups

Questions?

http://il.linkedin.com/in/vladikkhononov

http://twitter.com/vladikk

http://facebook.com/vladikk

http://vladikk.com

top related