CQRS in an hour or so - Chicago ALT.NET User Group

advertisement
CQRS in an hour or so
1
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!!!!!!!
2
Sources
• Greg Young
– http://codebetter.com/blogs/gregyoung/archive/2
009/08/13/command-query-separation.aspx
• Udi Dahan
– http://www.udidahan.com/2009/12/09/clarifiedcqrs/
• Mark Nijhof
– http://elegantcode.com/2009/11/11/cqrs-la-gregyoung/
3
CQRS
• CQRS = “Command Query Responsibility
Segregation”
• Huh?
• A design – pattern -architecture – Framework
– Principle – Something
• Makes stuff better
• Huh?
4
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.”
5
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
6
Nihjof #1
7
Nihjof #2
8
Nihjof Categories
•
•
•
•
1 – Queries
2 – Commands
3 – Internal Events
4 – External Events
9
UDI #1
10
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)
11
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))
;
•
}
•
}
12
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
13
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
14
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
15
Commands
• Commands can be queued
– Split into separate queues
• Scale where needed
• Commands don’t have to be handled by the
domain
16
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
17
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
18
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)
19
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
20
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
21
Questions?
22
Download