and queries. A command serves to modify objects, a query to return information about objects.” Bertrand Meyer ETH Zurich Text cited from: Object-Oriented Software Construction, second edition, 1997
Query Facade Query Services DTO DTO ORM DB Command Facade Command Services Domain Model ORM Domain Model Query Facade Query Services ORM Domain Model Query Facade Query Services ORM Domain Model Command and query parts can scale independently, e.g. to accommodate highly asymmetric load.
benefit from a specialized query model, optimized for quick data retrieval (de-normalized, pre- aggregated,...) User Interface Query Facade Query Services DTO DTO ORM DB Command Facade Command Services Command Model ORM Domain Model Query Facade Query Services ORM Domain Model Query Facade Query Services ORM Query Model
benefit from a specialized query model, optimized for quick data retrieval (de-normalized, pre- aggregated,...) User Interface Query Facade Query Services DTO DTO ORM DB Command Facade Command Services Command Model ORM Domain Model Query Facade Query Services ORM Domain Model Query Facade Query Services ORM Query Model ‣ validate and process commands ‣ keep data consistent ‣ guarantee ACID properties ‣ behaviour of domain model ‣ more difficult to scale ‣ rich query capabilities ‣ short response times ‣ different views on data ‣ potentially denormalized ‣ easier to scale
Facade Query Services DTO DTO ORM DB Command Facade Command Services Command Model Query Facade Query Services Query Facade Query Services SELECT … FROM … WHERE ... The default architecture for distributed business apps CQRSified Queries are just dealing with data, not with behavior. Why do we need objects?
cases, eventual consistency is sufficient. The data users are looking at in the UI is always stale to some extent. Query Services Query Services Thin Read Layer User Interface Query Facade Query Services DTO DTO ORM DB Command Facade Command Services Command Model Query Facade Query Services Query Facade Query Services SELECT … FROM … WHERE ... Query DB Query DB Query DB Event Handler Event Handler Event Handler Events Write
cases, users don’t care whether their actions have immediate effect – as long as they eventually get feedback. Query Services Query Services Thin Read Layer User Interface Query Facade Query Services CMD DTO ORM DB Command Facade Command Services Command Model Query Facade Query Services Query Facade Query Services SELECT … FROM … WHERE ... Query DB Query DB Query DB Event Handler Event Handler Event Handler Events Write Command Queue Commands update read model asynchronously
Facade Query Services CMD DTO DB Command Facade Command Services Command Model Query Facade Query Services Query Facade Query Services SELECT … FROM … WHERE ... Query DB Query DB Query DB Event Handler Event Handler Event Handler Events Write Command Queue Commands Processor The default architecture for distributed business apps CQRSified CQRS plays well with an Event Sourcing architecture – you just store events and re-create the state of domain objects as needed. event store
‣ changes to domain objects are the result of applying events ‣ events are immutable ‣ events are a representation of what has happened at a specific time Event Sourcing in a nutshell
in time just by replaying events up to that point in time ‣ allows you to analyse historic data based on detailed events that would otherwise have been lost ‣ gives you an audit log “for free” ‣ you can add new, optimized read models (potentially in-memory) later without migration hassle and such What’s so great about Event Sourcing?
asymmetrical. …if scaling your application is difficult. …if your domain model is bloated by complex domain logic, making queries inefficient. …if you can benefit from event sourcing.