+ All Categories
Home > Technology > Greenfield Development with CQRS

Greenfield Development with CQRS

Date post: 14-May-2015
Category:
Upload: resources-global-professionals
View: 3,922 times
Download: 2 times
Share this document with a friend
Description:
It's rare that you get a chance to build an applicaton the way you want to, from the ground up. If you did, what architectural choices would you make and why? Command Query Responsibility Segregation (CQRS) is a hot topic and has been described as crack for architecture addicts. This talk will look at why CQRS may be a good architectural choice for your project, how to use the NCQRS framework, and how this framework can be incorporated with ASP.NET MVC on the front-end and Azure on the back-end. This talk will also focus on the learning curve experienced when implementing an architectural style that bends the curve and is out of the mainstream of traditional application development.
Popular Tags:
35
Greenfield Development with CQRS David Hoerster Co-Founder and CTO, BrainCredits
Transcript
Page 1: Greenfield Development with CQRS

Greenfield Development with CQRS

David HoersterCo-Founder and CTO, BrainCredits

Page 2: Greenfield Development with CQRS

About Me

C# MVP (April 2011) Co-Founder of BrainCredits

(braincredits.com) Senior Technical Director for Resources

Global Professionals President of Pittsburgh .NET Users Group Organizer of recent Pittsburgh Code Camps Twitter - @DavidHoerster Blog –

http://geekswithblogs.net/DavidHoerster Email – [email protected]

Page 3: Greenfield Development with CQRS

Goals

Understanding the CQRS Architecture & Benefits (& Drawbacks) Commands Domain Objects Events Handlers

Incorporating into Azure Queues and Blobs

Fronting it with MVC

Page 4: Greenfield Development with CQRS

Pre-Requisites

Some knowledge and familiarity with Domain Driven Design

Some knowledge of Azure objects Some knowledge of ASP.NET MVC Leaving the notion that your data

store must be normalized to the Nth degree at the door

Page 5: Greenfield Development with CQRS

Backstory

Goals for BrainCredits.com Fast reads Scalable Handle, potentially, large volumes of

requests Be able to change quickly Ability to track user in system and events

that occur Easy to deploy, manage Inexpensive (FREE????)

Page 6: Greenfield Development with CQRS

Backstory

Decided to jump into cloud with Azure BizSpark company Hey, it’s the cloud! Scalability Deployment via VS2010 Pretty inexpensive – no HW to manage But how to store data and design

system?

Page 7: Greenfield Development with CQRS

Backstory

I would recommend to start looking along the CQRS style of architectures- Rinat Abdullin

Articles by Greg Young, Udi Dahan, J. Oliver, R. Abdullin

Page 8: Greenfield Development with CQRS

Traditional ArchitectureIssues Get all of the orders for user “David”

in last 30 days

Customer (SalesLT)CustomerID

NameStyle

Title

FirstName

MiddleName

LastName

Suffix

CompanyName

SalesPerson

EmailAddress

Product (SalesLT)ProductID

Name

ProductNumber

Color

StandardCost

ListPrice

Size

Weight

ProductCategoryID

ProductModelID

SellStartDate

SellEndDate

ProductCategory (SalesLT)ProductCategoryID

ParentProductCategoryID

Name

rowguid

ModifiedDate

ProductModel (SalesLT)ProductModelID

Name

CatalogDescription

rowguid

ModifiedDate

SalesOrderDetail (SalesLT)SalesOrderID

SalesOrderDetailID

OrderQty

ProductID

UnitPrice

UnitPriceDiscount

LineTotal

rowguid

ModifiedDate

SalesOrderHeader (SalesLT)SalesOrderID

RevisionNumber

OrderDate

DueDate

ShipDate

Status

OnlineOrderFlag

SalesOrderNumber

PurchaseOrderNumber

AccountNumber

CustomerID

ShipToAddressID

BillToAddressID

ShipMethod

CreditCardApprovalCode

SubTotal

TaxAmt

Freight

Page 9: Greenfield Development with CQRS

Traditional ArchitectureIssues

Get all the orders for user ‘David’ in last 30 days

SELECT c.FirstName, c.MiddleName, c.LastName, soh.SalesOrderID, soh.OrderDate, sod.UnitPrice, sod.OrderQty, sod.LineTotal, p.Name as 'ProductName', p.Color, p.ProductNumber, pm.Name as 'ProductModel', pc.Name as 'ProductCategory', pcParent.Name as 'ProductParentCategory'FROM SalesLT.Customer c INNER JOIN SalesLT.SalesOrderHeader soh

ON c.CustomerID = soh.CustomerIDINNER JOIN SalesLT.SalesOrderDetail sod ON soh.SalesOrderID =

sod.SalesOrderIDINNER JOIN SalesLT.Product p ON sod.ProductID = p.ProductIDINNER JOIN SalesLT.ProductModel pm ON p.ProductModelID =

pm.ProductModelIDINNER JOIN SalesLT.ProductCategory pc ON p.ProductCategoryID =

pc.ProductCategoryIDINNER JOIN SalesLT.ProductCategory pcParent ON

pc.ParentProductCategoryID = pcParent.ProductCategoryIDWHERE c.FirstName = 'David'

AND soh.OrderDate > (GETDATE()-30)

Page 10: Greenfield Development with CQRS

Traditional ArchitectureIssues

Wouldn’t it be great if it was something like?SELECT FirstName, MiddleName, LastName, SalesOrderID, OrderDate, UnitPrice, OrderQty, LineTotal, ProductName, Color, ProductNumber, ProductModel, ProductCategory, ProductParentCategoryFROM CustomerSalesWHERE FirstName = 'David'

AND OrderDate > (GETDATE()-30)

Page 11: Greenfield Development with CQRS

Traditional ArchitecureIssues

It seems that many applications cater to fast C-U-D operations, but the Reads suffer Highly normalized databases Updating a Product Name is easy

What would make querying faster? Reducing JOINS Flattening out our model Heresy!

Business logic and domain objects bleed through layers as a result, too.

Page 12: Greenfield Development with CQRS

What Alternatives Are There?

That’s where CQRS may be an option Provides for fast reads at the ‘expense’ of more

expensive writes Once the data is read by the client, it’s already old▪ A system that is eventually consistent is usually

acceptable▪ EVENTUAL CONSISTENCY!▪ The read model for the system eventually is consistent with the

system events

Allows for scalability very easily▪ Even in Azure!

Encapsulates business logic in the domain▪ Adheres strictly to CQS

Page 13: Greenfield Development with CQRS

What is CQRS

Command Query Responsibility Segregation Based upon Bertrand Meyer’s Command

Query Separation principle:“every method should either be a command that performs an action, or a query that returns data to the caller, but not both. In other words, asking a question should not change the answer” (Meyer)

In essence, commands return acknowledgement; queries return data.

Page 14: Greenfield Development with CQRS

What is CQRS

Taking this further, CQRS describes an architecture where commands are messages (possibly asynchronous) queries go against a read model

Since commands are returning void, it allows for the message to be transformed into the read model If we’re transforming the message, why not make the read

model as fast as possible? Since we’re transforming the message, perhaps we can

take a few extra ticks for additional processing This flips the conventional wisdom of fast writes and

slow reads Now we have fast reads and “slower” writes (since we’re

writing to a denormalized store)

Page 15: Greenfield Development with CQRS

What is CQRS

CQRS essentially splits your application into two parts The Read Side The Command Side

The Read Side requests data and receives it

The Command Side issues commands (inserts, updates, deletes) and receives just an acknowledgment that it was received.

Page 16: Greenfield Development with CQRS

What is CQRS (Simplified)

Client

Read Model Store

Event Store

Repository Command Service

Domain (ARs)

Denormalizer

Event Handler

Command Issued – ack/nackData Requested/Returned

Command SideQuery Side

Page 17: Greenfield Development with CQRS

Getting Started

Steps on the Command Side Command is issued Routed to proper Domain object method Domain raises zero, one or more Events Events handled by Denormalizer to

persist data to read model Each step is really one or more

messages being sent

Page 18: Greenfield Development with CQRS

Getting Started

You can roll your own, or use a framework

Several out there, including: NCQRS Lokad.CQRS Agr.CQRS on CodePlex (not much

activity) Axon (Java)

By using a framework, there are “extras”

Page 19: Greenfield Development with CQRS

CQRS Frameworks

With NCQRS (ncqrs.org), you get: CQRS support Event Sourcing Support for SQL or NoSQL event sourcing Snapshotting

Not always good things If you’re doing ‘pure’ or ‘true’ CQRS, then this is

good Otherwise, may be overkill

Don’t depend on the framework Let the framework help you, not constrict you

Page 20: Greenfield Development with CQRS

Demo – In Which David Turns To A Life-Long Desire – Buzzword Bingo

Demo – BuzzyGo

Page 21: Greenfield Development with CQRS

Command Side Flow

Command Domain

Event 1

Event 2

Event N

Handler 1

Handler 2

Handler N

ReadMode

l

Page 22: Greenfield Development with CQRS

Commands

Simple message from the client to the back-end requesting something to be done

Imperative tone CreateUser DeleteCard MarkSquare

Contains enough information for the back-end to process the request

No return value Maps to Aggregate Root’s constructor or

method

Page 23: Greenfield Development with CQRS

Domain

Command maps to a AR method/ctor Business logic happens here

May assume validation done on client, but can be done here

Business rules applied here▪ e.g. FREE space is in the middle and is automatically marked.

Once business rules applied, data is added to events that are applied. One or more events can be applied

Once event is applied, domain updates itself and is added to the event source repository

Not exposed to client, generally

Page 24: Greenfield Development with CQRS

Events

Simple messages from domain Similar to commands

But not the same Semantically different CardCreated; SquareMarked; CardWon

Has enough information for event handler to write information to the read model

Page 25: Greenfield Development with CQRS

Denormalizer (Handler)

Handles the events applied by the domain

Should NOT perform any validation or business rules

Its job is to perform minimal projections and transformations of data and then send that data to the repository/datastore

Repository/DataStore being updated is the read model

Page 26: Greenfield Development with CQRS

Read Side Flow

ReadModel

Query Provider(Repo/

WCFDS/etc)

Client

Request for Data

DTO

Query

Results

Page 27: Greenfield Development with CQRS

Where Can I Use CQRS?

Windows apps Services Web apps Cloud-based apps Really doesn’t matter

Just depends on the problem being solved

Page 28: Greenfield Development with CQRS

CQRS in the Cloud

Hosting CQRS in Azure Really no different on the web side than

a CQRS web app Typically, you’d want 2 roles

Web Role for the UI, which also performs querying

Worker Role for the Command handling Both roles can scale out as much as

needed Multiple web roles with a single worker

role, or vice versa or both!

Page 29: Greenfield Development with CQRS

Communication in theCloud

How do I issue commands from my web role? 2 typical solutions▪ WCF service on the worker role side▪ Use Azure storage features (blobs, queues, tables)

Both have advantages and disadvantages▪ WCF is by default synchronous, so you’ll need to

design for fire-and-forget▪ But can be easier to get up and running quickly

▪ Azure Storage has a lot of moving pieces▪ Watch out for transaction costs!

Page 30: Greenfield Development with CQRS

Using Azure Storage

General flow is this Web role issues a command by dropping

it in a blob container (name is GUID). Command blob name is then dropped in

a queue Worker role monitors queue for work When it finds a message in the queue, it

grabs blob from storage based on id in queue message

Deserializes command and then sends it through normal CQRS pipeline

Page 31: Greenfield Development with CQRS

CQRS in the Cloud

Controller

Queue

Blob Storage

Command

HandlerAzure Table

Storage

Domain

Event(s)

Denormalizer

Read Model

Repository

Page 32: Greenfield Development with CQRS

CQRS in the Cloud

ASP.NET MVC Controller Reading data is no different, going

through a Repository Writing data (issuing commands)

involves dropping command into Azure Queue

CloudHelper class facilitates this▪ Also provides LogMessage facility

Page 33: Greenfield Development with CQRS

CQRS in the Cloud

Using Azure Table Storage for logging user actions… Different than events. Want to know user

behavior. Storage is huge – just watch transaction costs▪ Consider batching log reads

But you can create replays of user interaction▪ Similar to event sourcing’s replay of events▪ Event sourcing doesn’t capture “Cancels” or

“Reads”, which may be useful from a marketing perspective

Page 34: Greenfield Development with CQRS

Claim Credit for thisSession

BrainCreditshttp://www.braincredits.com/Lesson/16852

Page 35: Greenfield Development with CQRS

Resources

CQRS Info Site – http://cqrsinfo.com NCQRS Site –http://ncqrs.org DDD/CQRS Google Group -

http://groups.google.com/group/dddcqrs Udi Dahan’s CQRS article “Clarified CQRS” –

http://www.udidahan.com/2009/12/09/clarified-cqrs/

Rinat Abdullin’s CQRS information – http://abdullin.com/cqrs

Distributed Podcast - http://distributedpodcast.com/


Recommended