CQRS in an hour or so
description
Transcript of CQRS in an hour or so
1
CQRS in an hour or so
2
Who is jdn?
• Me, aka John Nuechterlein• Blog: http://www.blogcoward.com• Operations Manager – Developer – Architect -
Raging Douchebag• eCom then Finance hopefully ecom again
background• Ph.D. in Philosophy (University of Miami at the
age of 25)– HI JEREMY!!!!!!!
3
Sources
• Greg Young– http://codebetter.com/blogs/gregyoung/archive/
2009/08/13/command-query-separation.aspx• Udi Dahan– http://www.udidahan.com/2009/12/09/clarified-
cqrs/• Mark Nijhof– http://elegantcode.com/2009/11/11/cqrs-la-greg-
young/
4
CQRS
• CQRS = “Command Query Responsibility Segregation”
• Huh?• A design – pattern -architecture – Framework
– Principle – Something• Makes stuff better• Huh?
5
CQS Defined
• Bertrand Meyer (via Wikipedia)• “Command Query Separation”– “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.”
6
CQRS defined
• Meyer: Separate command methods that change state from query methods that read state.
• Greg Young: Separate command messages that change state from query messages that read state.
• Can have significant architectural implications
7
Nihjof #1
8
Nihjof #2
9
Nihjof Categories
• 1 – Queries • 2 – Commands • 3 – Internal Events • 4 – External Events
10
UDI #1
11
Queries• ‘Reporting’
– Misleading description (Greg’s fault), but makes some sense• Simple Query Layer
– Simple views or sprocs or selects from denormalized tables• Simple DTOs, no mapping needed
– Don’t go through the Domain Model, as it pollutes it– ViewModel per query perhaps– Why should the data come across 5 layers through 3 model transformations to
populate a screen? (Udi)• ‘Traditional Reporting’
– Can (almost always will) have its own Model as well (and perhaps/probably its own data source)
• Synchronous, no messaging needed• Eventual Consistency (more later)
12
Queries• No mapping code, don’t even bother getting a domain object at all, e.g.:• public class ModelDetailBrickDTOMapper : IMapper<Model,
ModelDetailBrickDTO>• {• public ModelDetailBrickDTO Map(Model m)• {• return new ModelDetailBrickDTO(m.ID, m.Name,
m.Description, m.Details, m.ShippingMessage, m.GetPrice("Current"), m.GetPrice("MSRP"), m.Sizes, m.Images, DisplayProductBrick.GetRelatedDisplayProductBricksByModel(m));
• }• }
13
Queries
• Data store– Cache it (it’s already stale)– Why not on web-tier?– Why relational?
• Horizontal scalability– If you cache, add a new server to handle it
14
Commands
• Commands capture intent, DTOs don’t– CustomerDTO vs CustomerChangedAddressCommand
• Part of the ‘Ubiquitous’ Language• Handler per command• Can be validated outside of domain entities• This is why no getters/setters on domain entities, their
state is updated by processing commands according to the rules of the business
• This is why domain entities are never invalid, commands that would produce invalid state are rejected
15
Commands
• Separate Data Modification– Make preferred– Change address– Delinquent payment event example
• Comes in 1 ms after make preferred event• What to do?
– A generic DTO could do these things, of course, but after the fact, how do you know what actually happened?
• UI Implications– Excel-like screens don’t work– Commands require specific intent
16
Commands
• Commands can be queued– Split into separate queues• Scale where needed
• Commands don’t have to be handled by the domain
17
Internal Events
• Triggered by commands• Can be persisted– Could be RDBMS, ODBMS, Document DB, etc.– Event sourcing (big topic, punting)
• Can be replayed– Production support benefit
• Snapshots can also be created & persisted– Don’t delete original events
• Domain can accept command or reject it– Raise event either way
18
Internal Events• Write-only
– “Accountants don’t use erasers”• Compensating Actions/Events
– Instead of rolling back a transaction, you compensate for some failure
• Automatic audit log– You have all the events that happened
• No more ‘impedence mismatch’– You are persisting events, not rows
• Data mining– Like I said, you have all the events that happened
19
External Events
• Publishing– Typically, message bus– Could use views or ETL to process in a ‘simpler’
architecture• Data stores can subscribe• Only process when a read request comes in
(GY)
20
External Events
• Publishing external events and persisting internal events done in a transaction
• Eventual Consistency– Latency is almost always okay– Question is, how much?– Availability trumps correctness– Acting on incomplete data is normal
• Event handler per view model, perhaps
21
Why not CQRS?
• It’s new, it’s different, I’m stupid• Multiple data stores• Operational Complexity• Losing ACID/Transactions is scary• Lots of Commands and Events and Handlers
and Lions and Tigers and Bears oh my! to Code
22
Questions?