CQRS Crack for Architecture Addicts orAn Idea Whos











































































- Slides: 75
CQRS: Crack for Architecture Addicts… -or…An Idea Who’s Time Has Come?
Happy Birthday! Thanks for celebrating 10 years of the. NET Community with INETA
Tweet for Prizes Follow us at @ineta. Tweet using the hashtag #INETA 10 for a chance to win a prize in our daily random drawing throughout February.
Send Your Photo to Win Post your User Group photo and send us a link (at birthday@ineta. org) to be entered in the User Group weekly random drawing during February. We’ll post the link on the birthday page.
Birthday Video Grape. City is putting together a video featuring user group leaders. See the February newsletter for details and send your video clip to be included. http: //ineta. org/newsletters/2012_02. htm
Special offer from CODE Magazine INETA's birthday gift to you! A complimentary one year subscription to Code Magazine is available to all new subscribing U. S. Members. Go to www. codemag. com/subscrib e/ineta 10 to receive your free subscription!
Thank you Platinum Sponsors http: //www. componentone. com
Thank you Platinum Sponsors http: //www. esri. com
Thank you Platinum Sponsors http: //www. infragistics. com
Thank you Platinum Sponsors http: //www. telerik. com
Thank you Gold and Silver Sponsors http: //www. red-gate. com http: //www. grapecity. com
Thank you Donation Sponsors oreilly. com grapecity. com typemock. com
Thank you Donation Sponsors winconnections. com code-magazine. com ssware. com
About INETA provides structured, peer-based organizational, educational, and promotional support to the growing worldwide community of Microsoft®. NET user groups. http: //ineta. org
INETA Programs - Community Speakers program - Virtual Groups and Speakers - Community Champions - INETA Live! - Outreach and recognition for user groups - Offers from sponsors for groups and members http: //ineta. org
INETA Newsletter Keep up with news on programs, training, special events and other happenings in the world of the. NET community. Visit the link on the archive page and enter your email address to be added to the mailing list. http: //ineta. org/newsletters
Community Speakers Program Anyone can register to become part of the program. Group leaders can find speakers as often as you like. http: //ineta. org/Speakers/
INETA Live Learn something new with the community presentation recordings available now on INETA Live! http: //live. ineta. org/
Community Champions Tell us what you do to support the. NET Community and get recognized. http: //inetachamps. com
Get Your Code On and Win a scholarship and paid travel to either Dev. Connections in Las Vegas or Tech. Ed in Orlando with the Component Code Challenge. http: //ineta. org/Code. Challenge
Special Offers for INETA Members and Groups http: //ineta. org/offers
CQRS: Crack for Architecture Addicts… -or…An Idea Who’s Time Has Come?
Do I Suck? http: //speakerrate. com/talks/9298
Who am I? • …and why should you care? • Steve Bohlen • I Read Books + Write Software • vs. “Read Software + Write Books” • Blog, Screencast, Speak, Share, Learn
Nearly 20 years developing software LISP, Delphi, C/C++, VB. NET, C#, Ruby Senior Engineer Springsource/VMware Co-Founder, NYC Alt. Net User Group http: //nyalt. net Co-Organizer, NYC DDD User Group http: //dddnyc. org Contributor: various OSS projects Nhibernate http: //www. nhforge. org NDb. Unit http: //www. googlecode. com/ndbunit Spring. NET http: //www. springframework. net blog: http: //blog. unhandled-exceptions. com e-mail: sbohlen@gmail. com twitter: @sbohlen
Beta Presentation
Opinions Ahead
Agenda • What’s wrong with Traditional Application Architecture? • What is CQRS? • Commands and Events • Persistence • Understanding Event Sourcing • Exploring a simple CQRS sample app • Exploring a comprehensive CQRS sample app (? ) • Resources to Learn more • Q+A
What’s wrong with Traditional Application Architecture?
Traditional Architecture
Traditional Architecture Remote Services Domain Object Application Services RDBMS Domain Object ACK Returned LAN/WAN Command Request DTO Return DTO Client
Application Design Pain Points Scalability of System is by larger and larger RDBMS • Surprise, surprise! • Persistence means ‘save the Current State’ of the domain model • Query concerns are at odds with Transactional concerns • 1 NF vs. 3 NF • more… •
Domain Modeling Pain Points • • Business Rules only exist in user’s heads Converting Domain Objects to DTOs (and back again!) Domain Object Persistence Lazy vs. Eager Fetching Optimizing Domain for efficient Queries Setter/Getter Anti-Pattern Tests are (often) brittle more…
Business Pain Points • • Must know what business questions we want to ask up front Optimizing for Queries and Optimzing for Transactions are tied together (and expensive) Evolving Requirements is hard/expensive more…
Self-Delusion • • One model can be made to efficiently serve two (or more!) different masters Competing optimization needs of Queries and the Transactions can be efficiently balanced Getters/Setters are a necessary evil Persisting State is the only way to think about the problem
What is CQRS?
Command-Query Separation (CQS) states that 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. More formally, methods should return a value only if they are referentially transparent and hence possess no side effects. -Bertrand Meyer, designing the Eiffel language
Interface Segregation Principle
Command-Query Responsibility Segregation • The CQS principles applied to your domain modeling and system architecture • Enable each element of your architecture to be optimized for a single responsibility • Decomposition for your architecture rather than just for your objects
Slicing and Dicing our Architecture LAN/WAN Remote Services Server Domain Object Application Services Read RDBMS Write Domain Object ACK Returned Command Request DTO Client Return DTO Client
Refactoring our Architecture LAN/WAN ACK Returned Command Request DTO Return DTO Client Remote Services Domain Light-Weight Query Services Object Application Services Persistence Read RDBMS Eventually Write Persistence
Scaling our Systems Write C A P Read CAP Theorem: C onsistency, A vailability, P artition-Tolerance; pick any two!
About “Eventual Consistency” • Domain Experts deal in ‘stale’ data all the time – Edit screens, Reports, Analysis, OLAP • ‘Staleness’ is often already implicitly in our systems – Caching, Optimistic Concurrency, and more • Eventual Consistency is making that ‘staleness’ an explicit (and acknowledged) fact in the system • Language matters: say stale and older not out-of-date or inconsistent – Opportunity to actually discuss ‘how stale is OK? ’ – Often we make data stale without this discussion at all
Commands and Events in CQRS
Refresher: the Aggregate Root Pattern Aggregate Boundary Entity 1 Entity 2 Value. Object 1 Entity 3 Aggregate Boundary Value. Object 1 Entity 1 Value. Object 2 Value. Object 1 Value. Object 2
The BIG Idea Order. Placed Event Place. Order Command Aggregate Root Order Domain Object Event *or* Order. Not. Placed Event!
The even BIGGER Idea Aggregate Root Command Handler Event Aggregate Root Event Application Domain Event Handler Event Handler
Domain Testing (conceptual) Aggregate Root Command Handler Event Aggregate Root Event Input Output Event Handler Event Handler
Understanding Commands • Commands are directives to the domain to perform some action • Commands may be declined/rejected by the domain for various reasons • Processing a Command will result in 0: n Events raised • Commands are always in the imperative: – Place. Order, not Order. Placed – Recall: in DDD, lexical differences matter • Commands are a component of the Ubiquitous Language we use to describe our domain
Demystifying Commands public class Place. Order. Command { //properties public readonly Guid Order. Id; public readonly string Comment; //ctor public Place. Order. Command(Guid id, string comment) { Order. Id = id; Comment = comment; } }
Understanding Events • Events are the result of some action having already happened in the Domain • Events may never be declined/rejected; they are evidence that something already happened • Events are always in the past-tense: – Order. Placed, not Place. Order – Recall: in DDD, lexical differences matter • Events are a component of the Ubiquitous Language we use to describe our domain
Demystifying Events public class Order. Placed. Event { //properties public readonly Guid Order. Id; public readonly Guid Confirmation. Id; public readonly string Comment; //ctor public Order. Placed. Event(Guid order. Id, Guid confirmation. Id, string comment) { Order. Id = id; Confirmation. Id = id; Comment = comment; } }
Role of Commands and Events
Persistence in CQRS
Compromises in Persistence Needs • Query (read) optimization and Transaction (write) Optimization needs are in opposition – 1 NF for queries, 3 NF for transactions – Scalability needs (imbalanced Reads and Writes) • Even RDBMS vendors acknowledge this – OLTP vs OLAP • One set of optimizations shared between Read and Write will by definition be suboptimal for each
Choose the Proper Persistence • • Optimize the Read store for Queries Optimize the Write store for Transactions Let each side be designed for its single-purpose role Don’t try to twist a single persistence store into doing “double-duty” – It will do neither well • RDBMS is no longer our only choice for persistence – No. SQL choices offer different pros/cons
Event Sourcing in CQRS
Thinking More About Events • Events are past-tense • An Audit-Log of the entire Domain for the life of the system • A history of what happened over time – not a record of the state of the domain at a point in time
Event Sequencing vs. State
Event Sequencing vs. State Search for Product ID 1 Add Product ID 1 to Cart Search for Product ID 2 Add Product ID 2 to Cart Final State: Cart with Product ID 2 in it Remove Product ID 1 from Cart
Typical Application w Audit Log The System • Audit Log *might* be right • Have to remember to write to it “when important” • Side-effect of the system Audit Log
Typical Application w Event Log The System • Audit Log *must* be right • Entries are guaranteed to be recorded when needed • Core to the system’s function Audit Log
Interesting Event Possibilities If Events are a record of what happened in The Domain… • We can (re)create the current state of the Domain by “replaying” events from the log • If we want a point-in-time view of the system, we can (re)create the Domain at that time by “replaying” events just to that point – Historical State for “free” – Bug Reproduction
Event Store Concepts Read 8 7 6 5 4 3 Replay Forward Read to Beginning 9 9 8 snap 7 6 5 4 3 2 2 1 1 Replay 10 10
Events and Domain Persistence • Saving our Aggregate is just serializing events • Loading our Aggregate becomes: /* load the snapshot for this aggregate or if no snapshot, begin w/ empty ‘default’ */ var customer = customer. Repo. Load. By. Id(customer. Id); //replay the events to make its state ‘current’ customer. Replay. All. Events(); //customer ready to accept commands now Consider: Why do we need an ORM now? ? ?
Exploring a Simple CQRS Sample
Exploring a Comprehensive CQRS Sample
Should I do CQRS? Absolutely Not! …or at least “Probably Not”
Additional Resources Central Hub for All Things CQRS http: //www. cqrsinfo. com Udi Dahan’s on CQRS (et. al. ) http: //www. udidahan. com/2009/12/09/clarified-cqrs/ Simple CQRS Sample Application https: //github. com/gregoryyoung/m-r Comprehensive CQRS Sample Application https: //github. com/Mark. Nijhof/Fohjin Jonathan Oliver’s Post on his Event Store project http: //blog. jonathanoliver. com/2010/07/cqrs-event-store/ Rinat Abdulluin on Getting Started with CQRS http: //abdullin. com/cqrs/ Greg Young on Testing Using Events (video) http: //skillsmatter. com/podcast/design-architecture/talk-from-greg-young
Rate Me! http: //speakerrate. com/talks/9298