Top Banner
Command Query Responsibility Segregation (CQRS) Derek Comartin @derek_comartin CodeOpinion.com
25

Command Query Responsibility Segregation (CQRS)

May 11, 2015

Download

Technology

Derek Comartin

CQRS Tech Talk @ Windsor Hackforge
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Command Query Responsibility Segregation (CQRS)

Command Query Responsibility Segregation

(CQRS)

Derek Comartin

@derek_comartinCodeOpinion.com

Page 2: Command Query Responsibility Segregation (CQRS)

Agenda

• Why?

• Typical Architecture

• What is CQRS

• How to apply CQRS

• Other benefits

• Why Not?

• Takeaways

Page 3: Command Query Responsibility Segregation (CQRS)

Why?

• Complex Domain

• Read & Write Boundaries

• Divergent Change

• Scalability

• Skill Set Segregation

• Architecture Choices

Page 4: Command Query Responsibility Segregation (CQRS)

Typical Architecture

Data Storage

Domain Object

Domain Object

Application Service

Client

DTODTO

Facade

Page 5: Command Query Responsibility Segregation (CQRS)

Typical Architecture - Client Side

Request DTO

Modify/Rebuild

DTO

Send DTO to

Server Display DTO in

View

Ack/Nak Response

1

2

34

5

6

Page 6: Command Query Responsibility Segregation (CQRS)

XML of DTO

<BankAccount>

<Id>123</Id>

<CustomerId>456</CustomerId>

<Type>Savings</Type>

<Overdraft>200.00</Overdraft>

<InterestRate>0.0035</InterestRate>

<Active>True</Active>

</BankAccount>

Page 7: Command Query Responsibility Segregation (CQRS)

Typical Architecture - Analysis

• Simple & Common

• Tooling: ActiveRecord, ORM, AutoMapper.

• Data Driven

• Potentially Anemic Domain Model

• Hard to scale data storage

Page 8: Command Query Responsibility Segregation (CQRS)

Command Query Separation

Every method should either be a commandthat performs an action, or a query that returns data to the caller, but not both.

Page 9: Command Query Responsibility Segregation (CQRS)

Command Query Responsibility Segregation

”CQRS is simply the creation of two objects where there was previously only one.”

-Greg Young

Page 10: Command Query Responsibility Segregation (CQRS)

Typical Service

BankAccountService

{

BankAccount CreateBankAccount(BankAccount);

BankAccount GetBankAccount(AccountId);

decimal UpdateBalance(AccountId, Balance);

void UpdateBankAccount(BankAccount);

decimal GetBankAccountBalance(AccountId);

}

Page 11: Command Query Responsibility Segregation (CQRS)

CQRS Services

BankAccountReadService

{

BankAccount GetBankAccount(AccountId);

decimal GetBankAccountBalance(AccountId);

}

BankAccountWriteService

{

BankAccount CreateBankAccount(BankAccount);

decimal UpdateBalance(AccountId, Balance);

void UpdateBankAccount(BankAccount);

}

Page 12: Command Query Responsibility Segregation (CQRS)

"Defining the CQRS pattern is easy. Realizing the benefits that implementing the CQRS pattern can

offer is not always so straightforward."

– Microsoft Patterns & Practices

"This simple notion leads to some profound consequences for the design of information

systems."

–Martin Fowler

Page 13: Command Query Responsibility Segregation (CQRS)

Complex Domain

• (Distributed) Domain Driven Design

• Behavior

• Intent

Page 14: Command Query Responsibility Segregation (CQRS)

Typical Architecture

Data Storage

Domain Object

Domain Object

Application Service

Client

DTODTO

Facade

Page 15: Command Query Responsibility Segregation (CQRS)

Simple CQRS

Data Storage

Domain Object

Domain Object

Application Service

Client

CommandDTO

Facade

Read Layer

Facade

QueryDTO

Page 16: Command Query Responsibility Segregation (CQRS)

CQRS - Client Side

Request DTO

Build Command

Object

Send Command

Object to Server Display DTO in

View

Ack/Nak Response

(optional)

1

2

34

5

6

Page 17: Command Query Responsibility Segregation (CQRS)

Command = Intent

DepositCommand

{

Guid AccountId;

decimal DepositAmount;

}

Page 18: Command Query Responsibility Segregation (CQRS)

CQRS Services

BankAccountReadService

{

BankAccountViewModel GetBankAccount(AccountId);

decimal GetBankAccountBalance(AccountId);

}

BankAccountWriteService

{

void Send(OpenBankAccountCommand);

void Send(DepositCommand);

void Send(WithdrawlCommand);

void Send(DeactivateCommand);

}

Page 19: Command Query Responsibility Segregation (CQRS)

More Options

• Multiple Models

• Domain Model = 3rd Normal Form

• Read Model = 1st Normal Form

Page 20: Command Query Responsibility Segregation (CQRS)

Read & Write BoundariesDivergent Change

Data Storage

Domain Object

Domain Object

Application Service

Client

CommandDTO

Facade

Read Layer

Facade

QueryDTO

Page 21: Command Query Responsibility Segregation (CQRS)

Skill Set Segregation

Data Storage

Domain Object

Domain Object

Application Service

Client

CommandDTO

Facade

Read Layer

Facade

QueryDTO

Page 22: Command Query Responsibility Segregation (CQRS)

Scalability

Data StorageDomain Object

Domain Object

Command Handlers

Client

CommandDTO

Message Queue

Read Layer

Facade

QueryDTO

Event Storage

Events

Message Queue Event Handlers

Data Storage

Page 23: Command Query Responsibility Segregation (CQRS)

Notes

• CRUD (not with DDD)

• Not top level architecture

• Determine per bounded context

Page 24: Command Query Responsibility Segregation (CQRS)

Takeaways

• Separate reads and writes between two objects.

• That’s it.

• Everything else (DDD, Event Sourcing, Messaging…) is not CQRS. They just fit extremely well.

Page 25: Command Query Responsibility Segregation (CQRS)

Resources

Greg Young

@gregyoung

goodenoughsoftware.net

Udi Dahan

@udidahan

udidahan.com

Microsoft Patterns & Practices

CQRS Journey