CQRS in an hour or so
description
Transcript of CQRS in an hour or so
![Page 1: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/1.jpg)
1
CQRS in an hour or so
![Page 2: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/2.jpg)
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!!!!!!!
![Page 3: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/3.jpg)
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/
![Page 4: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/4.jpg)
4
CQRS
• CQRS = “Command Query Responsibility Segregation”
• Huh?• A design – pattern -architecture – Framework
– Principle – Something• Makes stuff better• Huh?
![Page 5: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/5.jpg)
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.”
![Page 6: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/6.jpg)
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
![Page 7: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/7.jpg)
7
Nihjof #1
![Page 8: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/8.jpg)
8
Nihjof #2
![Page 9: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/9.jpg)
9
Nihjof Categories
• 1 – Queries • 2 – Commands • 3 – Internal Events • 4 – External Events
![Page 10: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/10.jpg)
10
UDI #1
![Page 11: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/11.jpg)
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)
![Page 12: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/12.jpg)
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));
• }• }
![Page 13: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/13.jpg)
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
![Page 14: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/14.jpg)
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
![Page 15: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/15.jpg)
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
![Page 16: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/16.jpg)
16
Commands
• Commands can be queued– Split into separate queues• Scale where needed
• Commands don’t have to be handled by the domain
![Page 17: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/17.jpg)
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
![Page 18: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/18.jpg)
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
![Page 19: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/19.jpg)
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)
![Page 20: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/20.jpg)
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
![Page 21: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/21.jpg)
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
![Page 22: CQRS in an hour or so](https://reader036.fdocuments.us/reader036/viewer/2022062520/56816176550346895dd102f9/html5/thumbnails/22.jpg)
22
Questions?