KEMBAR78
CQRS: Command/Query Responsibility Segregation | PPTX
A scalable pattern for building large multi-user system




Brian Ritchie                  Twitter: @brian_ritchie
Chief Architect                Email: brian.ritchie@gmail.com
PaySpan, Inc.                  Blog: http://weblog.asp.net/britchie
                               Web: http://www.dotnetpowered.com
Brian Ritchie
» Chief Architect at PaySpan, Inc.
» Nearly 20 years of development
  experience
» Developing on .NET since 1.0
  Beta 1
» Contributed to Mono and other
  open source projects
Agenda
» What is CQRS anyway?
» Why is it needed?
» How does CQRS work?
» When should I use CQRS?
» Review example implementation
» According to Wikipedia:
  "CQRS is simply the creation of two objects
  where there was previously only one. The
  separation occurs based upon whether the
  methods are a command or a query (the same
  definition that is used by Meyer in Command
  and Query Separation, a command is any
  method that mutates state and a query is any
  method that returns a value)."
Put another way…
  Command/Query Responsibility Segregation (CQRS) is the
  idea that you can use a different model to update
  information than the model you use to read information.

In this context,
» Commands = Writes
» Queries = Reads

Pioneered by Greg Young & Udi Dahan
Let’s take a step back. Why do we build applications like we do today?

                                           It started with a stack of paper…




                                 …that needed to be keyed
        …and along came              into the machine
         the CRUD app!
Being good developers, we didn’t stop there. We built various models to
      protect us from change at different layers of the application.




                                              Diagram © Martin Fowler
But this wasn’t scalable…so we add more layers.




Not only did we add layers, but also complexity.
» All of this to provide scalability & a consistent view
  of the data.

                 But did we succeed?
Back to our CRUD app…



                                                             ?
                          ?



   ?          ?
                                                             ?
                          ?




Where is the consistency? We have stale data all over the place!
To understand this better, let’s look at a basic multi-user system.




                    Retrieve data
                                            Retrieve data

User is looking at stale
          data                                               Modify data




            Stale data is inherent in a multi-user system.
     The machine is now the source of truth…not a piece of paper.
Which begs the question…

» Is the data the user is looking at right now stale?
» Since stale data always exists,    No, we need a different
  is all of this complexity really   approach.
  needed to scale?
                                     One that…
                                     » Offers extreme scalability
                                     » Inherently handle multiple
                                       users
                                     » Can grow to handle
                                       complex problems without
                                       growing development costs
Which brings us
back to CQRS…



           Command captures the
             intent of the user


                                                                          Scale out
                                                                          as many
                                                                          copies as
                                                                           needed



                                                                            Persistent View Model schema
           After database is                                                   matches UI view model
           updated, publish
         result to view model
                                                         Diagram from Rinat Abdullin
                                                         http://abdullin.com/cqrs
                                    A queue can be
                                  utilized to optimize
                                  write performance
Let’s break it down…
Common components of the CQRS pattern:
» Task-based UI
» Commands
» Domain Objects
» Events
» Persistent View Model


             Note: these are common components…not required components
Task-based UI
Task-based UI
Why rethink the User Interface?
» Grids don’t capture the user’s intent
Task-based UI
Rethinking the User Interface
» Adjust UI design to capture intent
   ˃ what did the user really mean?
   ˃ intent becomes a command

» Why is intent important?
   ˃ Last name changed because of misspelling
   ˃ Last name changed because of marriage
   ˃ Last name changed because of divorce

» User interface can affect your architecture
Task-based UI
» Validation
   ˃ increase likelihood of command succeeding
   ˃ validate client-side
   ˃ optimize validation using persistent view model

» What about user feedback?
   ˃ Polling: wait until read model is updated
   ˃ Use asynchronous messaging such as email
       “Your request is being processed. You will receive an email
       when it is completed”
   ˃ Just fake it!
       Scope the change to the current user. Update a local in-
       memory model
Commands
Commands
» Commands encapsulate the user’s intent but do
  not contain business logic, only enough data for
  the command
» What makes a good command?
   ˃A command is an action – starts with a verb
   ˃The kind you can reply with: “Thank you. Your confirmation
    email will arrive shortly”. Inherently asynchronous.
» Commands can be considered messages
   ˃Messaging provides an asynchronous delivery mechanism
    for the commands. As a message, it can be
    routed, queued, and transformed all independent of the
    sender & receiver
Commands & Domain Objects
» The domain model is utilized for processing
  commands; it is unnecessary for queries.
» Unlike entity objects you may be used
  to, aggregate roots in CQRS only have methods (no
  getters/setters)
  Aggregate Roots
  Some things belong together, like Apple Pie and Ice Cream, or Sonny and
  Cher. And so it is with Entities and Value Objects (VOs) – some of them
  belong together. Aggregates are groups of things that belong together. An
  Aggregate Root is the thing that holds them all together.
  Example: OrderLines have no reason to exist without their parent Order, nor can they belong to
  any other Order. In this case, Order and OrderLines would be an Aggregate, and the Order
  would be the Aggregate Root
Commands & Domain Objects
» Setters are an anti pattern in your domain. DDD is not about
  modeling data, or nouns. It is about modeling behaviors that
  are solving the domain problem, or verbs.
» The public interface of your domain should solely consist in
  public methods on your aggregate roots. The idea is that each
  method represents a use case.
» From a design perspective, it is also the only way to ensure
  your objects invariants. That way, your aggregates are always
  fully consistent – they valid state at all times.
» If DDD is about behavior, then getters also should be an anti
  pattern. And they are.

                         Julienn Letrouit http://julienletrouit.com/?p=22
Events
Events
» Events describe changes in the system state
» An Event Bus can be utilized to dispatch events to
  subscribers
» Events primary purpose update the read model
» Events can also provider integration with external systems
» CQRS can also be used in conjunction with Event Sourcing.
 Event Sourcing
 Captures all changes to an application state as a sequence of events. The
 current state is constructed by applying the events in the order they were
 recorded. Not only does it give us the current state, but we can also use the
 event log to reconstruct past states, and as a foundation to automatically adjust
 the state to cope with retroactive changes.
 Summarized from Martin Fowler – http://martinfowler.com/eaaDev/EventSourcing.html
Persistent View Model
Persistent View Model

» Reads are usually the most common activity –
  many times 80-90%. Why not optimize them?
» Read model is based on how the user wants to see
  the data.
» Read model can be denormalized
  RDBMS, document store, etc.
» Reads from the view model don’t need to be
  loaded into the domain model, they can be bond
  directly to the UI.
Persistent View Model


                      UI
                                 Query only…keep it simple



            Persistent View Model


           For each view in the UI,
       have a view/table in the database

SELECT * FROM ViewModelTable (WHERE ID = @ID)
Persistent View Model
              Data Duplicated, No Relationships, Data Pre-Calculated
Customer Service Rep view                              Supervisor view
          List of customers                            List of customers
ID        Name    Phone                 ID      Name     Phone Lifetime value




          Rep_Customers_Table                     Supervisor_Customers_Table
     ID          Name           Phone     ID      Name        Phone        Lifetime Value
First off, when should I avoid it?
» CQRS can be overkill for simple applications.
» Don’t use it in a non-collaborative domain or
  where you can horizontally add more database
  servers to support more users/requests/data at
  the same time you’re adding web servers – there
  is no real scalability problem – Udi Dahan
CQRS is a pattern that is usually leveraged for a portion of a
system.
» This builds on a concept from Domain Driven Design (DDD)
   known as a Bounded Context.
  Bounded Context
  A Bounded Context is an area of your application which has explicitly defined borders, has it’s own
  model, has it’s own Model, and maintains it’s own code. - Jak Charlton

  A Bounded Context can be considered as a miniature application, containing it’s own
  domain, code and persistence mechanisms. Within a Bounded Context, there should be logical
  consistency, each Bounded Context should be independent of any other Bounded Context. -
  ThinkDDD.org

» A typical application there are multiple bounded
  contexts, any of which can be implemented the way it
  makes sense.
Guidelines for using CQRS:
» Large, multi-user systems CQRS is designed to address
  concurrency issues.
» Scalability matters With CQRS you can achieve great read
  and write performance. The system intrinsically supports
  scaling out. By separating read & write operations, each
  can be optimized.
» Difficult business logic CQRS forces you to not mix domain
  logic and infrastructural operations.
» Large or Distributed teams you can split development tasks
  between different teams with defined interfaces.
Commands are simple object that contain all the data to perform the underlying action. They
                          also express intent by there name.
An Command Executors accepts commands of a certain type and performs a corresponding
 action. The action should not contain business logic and should directly use the domain.
All events that have occurred end up in the event store. It contains all the event that
represents the state changes in the system. These can be used to build up the current state by
  replaying them all. This store can also be used to fill up new or repair existing read model.




                      For the event store, NCQRS supports
                  MSSQL, MongoDB, RavenDB, SqlLite, and more…
NCQRS provides a base class for denormalizers that allows them
             to be subscribed to the event bus.
Command / Query Responsibility Segregation
                  A scalable pattern for building large multi-user system




Brian Ritchie                          Twitter : @brian_ritchie
Chief Architect                        Email: brian.ritchie@gmail.com
PaySpan, Inc.                          Blog: http://weblog.asp.net/britchie
                                       Web: http://www.dotnetpowered.com
Command / Query Responsibility Segregation
                  A scalable pattern for building large multi-user system




Brian Ritchie                          Twitter : @brian_ritchie
Chief Architect                        Email: brian.ritchie@gmail.com
PaySpan, Inc.                          Blog: http://weblog.asp.net/britchie
                                       Web: http://www.dotnetpowered.com

CQRS: Command/Query Responsibility Segregation

  • 1.
    A scalable patternfor building large multi-user system Brian Ritchie Twitter: @brian_ritchie Chief Architect Email: brian.ritchie@gmail.com PaySpan, Inc. Blog: http://weblog.asp.net/britchie Web: http://www.dotnetpowered.com
  • 2.
    Brian Ritchie » ChiefArchitect at PaySpan, Inc. » Nearly 20 years of development experience » Developing on .NET since 1.0 Beta 1 » Contributed to Mono and other open source projects
  • 3.
    Agenda » What isCQRS anyway? » Why is it needed? » How does CQRS work? » When should I use CQRS? » Review example implementation
  • 4.
    » According toWikipedia: "CQRS is simply the creation of two objects where there was previously only one. The separation occurs based upon whether the methods are a command or a query (the same definition that is used by Meyer in Command and Query Separation, a command is any method that mutates state and a query is any method that returns a value)."
  • 6.
    Put another way… Command/Query Responsibility Segregation (CQRS) is the idea that you can use a different model to update information than the model you use to read information. In this context, » Commands = Writes » Queries = Reads Pioneered by Greg Young & Udi Dahan
  • 8.
    Let’s take astep back. Why do we build applications like we do today? It started with a stack of paper… …that needed to be keyed …and along came into the machine the CRUD app!
  • 9.
    Being good developers,we didn’t stop there. We built various models to protect us from change at different layers of the application. Diagram © Martin Fowler
  • 10.
    But this wasn’tscalable…so we add more layers. Not only did we add layers, but also complexity.
  • 11.
    » All ofthis to provide scalability & a consistent view of the data. But did we succeed?
  • 12.
    Back to ourCRUD app… ? ? ? ? ? ? Where is the consistency? We have stale data all over the place!
  • 13.
    To understand thisbetter, let’s look at a basic multi-user system. Retrieve data Retrieve data User is looking at stale data Modify data Stale data is inherent in a multi-user system. The machine is now the source of truth…not a piece of paper.
  • 14.
    Which begs thequestion… » Is the data the user is looking at right now stale?
  • 15.
    » Since staledata always exists, No, we need a different is all of this complexity really approach. needed to scale? One that… » Offers extreme scalability » Inherently handle multiple users » Can grow to handle complex problems without growing development costs
  • 16.
    Which brings us backto CQRS… Command captures the intent of the user Scale out as many copies as needed Persistent View Model schema After database is matches UI view model updated, publish result to view model Diagram from Rinat Abdullin http://abdullin.com/cqrs A queue can be utilized to optimize write performance
  • 17.
    Let’s break itdown… Common components of the CQRS pattern: » Task-based UI » Commands » Domain Objects » Events » Persistent View Model Note: these are common components…not required components
  • 18.
  • 19.
    Task-based UI Why rethinkthe User Interface? » Grids don’t capture the user’s intent
  • 20.
    Task-based UI Rethinking theUser Interface » Adjust UI design to capture intent ˃ what did the user really mean? ˃ intent becomes a command » Why is intent important? ˃ Last name changed because of misspelling ˃ Last name changed because of marriage ˃ Last name changed because of divorce » User interface can affect your architecture
  • 21.
    Task-based UI » Validation ˃ increase likelihood of command succeeding ˃ validate client-side ˃ optimize validation using persistent view model » What about user feedback? ˃ Polling: wait until read model is updated ˃ Use asynchronous messaging such as email “Your request is being processed. You will receive an email when it is completed” ˃ Just fake it! Scope the change to the current user. Update a local in- memory model
  • 22.
  • 23.
    Commands » Commands encapsulatethe user’s intent but do not contain business logic, only enough data for the command » What makes a good command? ˃A command is an action – starts with a verb ˃The kind you can reply with: “Thank you. Your confirmation email will arrive shortly”. Inherently asynchronous. » Commands can be considered messages ˃Messaging provides an asynchronous delivery mechanism for the commands. As a message, it can be routed, queued, and transformed all independent of the sender & receiver
  • 24.
    Commands & DomainObjects » The domain model is utilized for processing commands; it is unnecessary for queries. » Unlike entity objects you may be used to, aggregate roots in CQRS only have methods (no getters/setters) Aggregate Roots Some things belong together, like Apple Pie and Ice Cream, or Sonny and Cher. And so it is with Entities and Value Objects (VOs) – some of them belong together. Aggregates are groups of things that belong together. An Aggregate Root is the thing that holds them all together. Example: OrderLines have no reason to exist without their parent Order, nor can they belong to any other Order. In this case, Order and OrderLines would be an Aggregate, and the Order would be the Aggregate Root
  • 25.
    Commands & DomainObjects » Setters are an anti pattern in your domain. DDD is not about modeling data, or nouns. It is about modeling behaviors that are solving the domain problem, or verbs. » The public interface of your domain should solely consist in public methods on your aggregate roots. The idea is that each method represents a use case. » From a design perspective, it is also the only way to ensure your objects invariants. That way, your aggregates are always fully consistent – they valid state at all times. » If DDD is about behavior, then getters also should be an anti pattern. And they are. Julienn Letrouit http://julienletrouit.com/?p=22
  • 26.
  • 27.
    Events » Events describechanges in the system state » An Event Bus can be utilized to dispatch events to subscribers » Events primary purpose update the read model » Events can also provider integration with external systems » CQRS can also be used in conjunction with Event Sourcing. Event Sourcing Captures all changes to an application state as a sequence of events. The current state is constructed by applying the events in the order they were recorded. Not only does it give us the current state, but we can also use the event log to reconstruct past states, and as a foundation to automatically adjust the state to cope with retroactive changes. Summarized from Martin Fowler – http://martinfowler.com/eaaDev/EventSourcing.html
  • 28.
  • 29.
    Persistent View Model »Reads are usually the most common activity – many times 80-90%. Why not optimize them? » Read model is based on how the user wants to see the data. » Read model can be denormalized RDBMS, document store, etc. » Reads from the view model don’t need to be loaded into the domain model, they can be bond directly to the UI.
  • 30.
    Persistent View Model UI Query only…keep it simple Persistent View Model For each view in the UI, have a view/table in the database SELECT * FROM ViewModelTable (WHERE ID = @ID)
  • 31.
    Persistent View Model Data Duplicated, No Relationships, Data Pre-Calculated Customer Service Rep view Supervisor view List of customers List of customers ID Name Phone ID Name Phone Lifetime value Rep_Customers_Table Supervisor_Customers_Table ID Name Phone ID Name Phone Lifetime Value
  • 32.
    First off, whenshould I avoid it? » CQRS can be overkill for simple applications. » Don’t use it in a non-collaborative domain or where you can horizontally add more database servers to support more users/requests/data at the same time you’re adding web servers – there is no real scalability problem – Udi Dahan
  • 33.
    CQRS is apattern that is usually leveraged for a portion of a system. » This builds on a concept from Domain Driven Design (DDD) known as a Bounded Context. Bounded Context A Bounded Context is an area of your application which has explicitly defined borders, has it’s own model, has it’s own Model, and maintains it’s own code. - Jak Charlton A Bounded Context can be considered as a miniature application, containing it’s own domain, code and persistence mechanisms. Within a Bounded Context, there should be logical consistency, each Bounded Context should be independent of any other Bounded Context. - ThinkDDD.org » A typical application there are multiple bounded contexts, any of which can be implemented the way it makes sense.
  • 34.
    Guidelines for usingCQRS: » Large, multi-user systems CQRS is designed to address concurrency issues. » Scalability matters With CQRS you can achieve great read and write performance. The system intrinsically supports scaling out. By separating read & write operations, each can be optimized. » Difficult business logic CQRS forces you to not mix domain logic and infrastructural operations. » Large or Distributed teams you can split development tasks between different teams with defined interfaces.
  • 36.
    Commands are simpleobject that contain all the data to perform the underlying action. They also express intent by there name.
  • 37.
    An Command Executorsaccepts commands of a certain type and performs a corresponding action. The action should not contain business logic and should directly use the domain.
  • 38.
    All events thathave occurred end up in the event store. It contains all the event that represents the state changes in the system. These can be used to build up the current state by replaying them all. This store can also be used to fill up new or repair existing read model. For the event store, NCQRS supports MSSQL, MongoDB, RavenDB, SqlLite, and more…
  • 39.
    NCQRS provides abase class for denormalizers that allows them to be subscribed to the event bus.
  • 40.
    Command / QueryResponsibility Segregation A scalable pattern for building large multi-user system Brian Ritchie Twitter : @brian_ritchie Chief Architect Email: brian.ritchie@gmail.com PaySpan, Inc. Blog: http://weblog.asp.net/britchie Web: http://www.dotnetpowered.com
  • 41.
    Command / QueryResponsibility Segregation A scalable pattern for building large multi-user system Brian Ritchie Twitter : @brian_ritchie Chief Architect Email: brian.ritchie@gmail.com PaySpan, Inc. Blog: http://weblog.asp.net/britchie Web: http://www.dotnetpowered.com