Introduction to CQRS (Command Query Responsibility Segregation)
-
Upload
globallogic-ukraine -
Category
Engineering
-
view
294 -
download
1
description
Transcript of Introduction to CQRS (Command Query Responsibility Segregation)
![Page 1: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/1.jpg)
©2014 GlobalLogic Inc. CONFIDENTIAL
![Page 2: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/2.jpg)
2 CONFIDENTIAL
Introduction to CQRS
Oleksandr Loktyev
![Page 3: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/3.jpg)
3 CONFIDENTIAL
Command-query separation (CQS)
Introduction to CQRS
A method should either change the state of an object or return a result, but not both.
1. Queries. Return results.
2. Commands. Change state.
Pros
• Method intents are well understood
• No side effects
![Page 4: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/4.jpg)
4 CONFIDENTIAL
Command query responsibility segregation (CQRS)
Introduction to CQRS
• A pattern based on CQS principle.
• Conceptual model is split into separate models depending whether it is a Command or Query.
![Page 5: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/5.jpg)
5 CONFIDENTIALIntroduction to CQRS
CustomerService
Customer GetCustomer(CustomerId) CustomerSet GetCustomersWithName(Name) void CreateCustomer(Customer) void EditCustomerDetails(CustomerDetails)
Applying CQRS on this would result in two services:
CustomerServiceCommands
void CreateCustomer(Customer) void EditCustomerDetails(CustomerDetails)
CustomerServiceQueries
Customer GetCustomer(CustomerId) CustomerSet GetCustomersWithName(Name)
![Page 6: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/6.jpg)
6 CONFIDENTIALIntroduction to CQRS
And that’s it!
There is nothing more to it than that…
![Page 7: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/7.jpg)
7 CONFIDENTIAL
Typical web architecture
Introduction to CQRS
![Page 8: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/8.jpg)
8 CONFIDENTIAL
Domain objects are natural for CrUD operations
Introduction to CQRS
public void Undismiss(DismissedObjectDTO dto)
{
var dismissedObject = _uow.DismissedObjectRepository.Get (dto.ObjectId, dto.ObjectTypeId);
dismissedObject.EndDate = DateTime.Now;
_uow.DismissedObjectRepository.Save(dismissedObject);
if (dismissedObject.ObjectType.ID == (int) Enums.CoachingObjectType.Observation)
{
var reviewDetail = _uow.EventReviewDetailDAO.Get(dto.ObjectId);
erd.ObservationScore = 100;
_uow.EventRepository.Save(erd);
}
_uow.CommitChanges();
}
![Page 9: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/9.jpg)
9 CONFIDENTIAL
But can be extremely inefficient for reads
Introduction to CQRS
Lazy loading:
public Company GetCameraCompany(Camera camera)
{
return camera.Vehicle.Driver.Company;
}
![Page 10: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/10.jpg)
10 CONFIDENTIAL
One more example
Introduction to CQRS
Incorrect fetching strategy.
private static void SomeOperation(List<Customer> customers)
{
foreach (var customer in customers)
{
foreach (var order in customer.Orders)
{
// do something
}
}
}
![Page 11: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/11.jpg)
11 CONFIDENTIAL
Something that is more natural for Read operation
Introduction to CQRS
Plain data instead of Domain Model.
private static void SomeOperation(List<Customer> customers)
{
var customerOrderDTO = _uow.customerRepository.GetCustomerOrders(customers);
foreach (var order in customerOrderDTO .Orders)
{
// do something
}
}
![Page 12: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/12.jpg)
12 CONFIDENTIAL
Queries
Introduction to CQRS
• What’s the purpose of queries? To show data. Not objects.
• So why should the data from the database come across 5 layers through 3 model transformations? It’s a bit overkill to display data.
• Why not just this: The UI read data from the database and displays it?
![Page 13: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/13.jpg)
13 CONFIDENTIALIntroduction to CQRS
Consequence 1
Commands and queries use the same data but they should not necessarily use the same data model
![Page 14: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/14.jpg)
14 CONFIDENTIAL
CQRS way
Introduction to CQRS
It is natural to use a different model to update information than the model you use to read information.
![Page 15: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/15.jpg)
15 CONFIDENTIAL
Simple query for grid
Introduction to CQRS
SELECT
c.Name, o.Name, ot.Type
FROM Customer c
INNER JOIN CustomerOrder co ON co.CustomerId = c.CustomerId
INNER JOIN Order o ON co.OrderId = c.OrderId
INNER JOIN OrderType ot ON o.OrderId = ot.OrderId
WHERE
o.CustomerId = 20
AND ot.Type = ‘Active’
![Page 16: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/16.jpg)
16 CONFIDENTIAL
What if the query is slow?
Introduction to CQRS
1. Execution plan and query optimization.
2. Add indexes.
3. Move to stored procedure.
4. Completely remove ORM.
The fact is that some queries simply cannot be quick.
![Page 17: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/17.jpg)
17 CONFIDENTIAL
Let’s add denormalization
Introduction to CQRS
SELECT
CustomerName, OrderName, OrderType
FROM CustomerOrderView co
WHERE
CustomerId = 20
AND OrderType = ‘Active’
![Page 18: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/18.jpg)
18 CONFIDENTIALIntroduction to CQRS
Consequence 2
Database can contain denormalized data for reads
![Page 19: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/19.jpg)
19 CONFIDENTIAL
CQRS way
Introduction to CQRS
Queries tend to use denormalized data rather then classical database approach.
![Page 20: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/20.jpg)
20 CONFIDENTIAL
Let’s go further and separate storages
Introduction to CQRS
![Page 21: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/21.jpg)
21 CONFIDENTIAL
Read storage can be actually anything you want
Introduction to CQRS
![Page 22: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/22.jpg)
22 CONFIDENTIAL
How to populate read storage? Synchronous way.
Introduction to CQRS
![Page 23: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/23.jpg)
23 CONFIDENTIAL
How to populate read storage? Async way.
Introduction to CQRS
![Page 24: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/24.jpg)
24 CONFIDENTIAL
CQRS is …
Introduction to CQRS
• CQRS is a small tactical pattern
• CQRS is learnable in 5 minutes
• CQRS can open many doors
![Page 25: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/25.jpg)
25 CONFIDENTIALIntroduction to CQRS
Benefits• Handles domain complexity
• Applies different optimization strategies for reads and writes
• Scalability
When to use• Complex domains
• High performance applications
• Only on specific portions of a system (Bounded Context in DDD)
![Page 26: Introduction to CQRS (Command Query Responsibility Segregation)](https://reader035.fdocuments.net/reader035/viewer/2022081801/547d9998b47959c5508b4958/html5/thumbnails/26.jpg)
26 CONFIDENTIAL
Questions?