[CQRS Journey] Journey 4 : Extending and Enhancing the Orders and Registrations Bounded Context
04 Jan 2020Changes to the bounded context
- topics
- Improvements to the way message correlation works with the RegistrationProcessManager class
- Implementing a record locator to enable a registrant to retrieve an order that she saved during a previous session
- Adding a countdown timer to the UI to enable a registrant to track how much longer they have to complete an order
- Supporting orders for multiple seat types simultaneously
- CQRS command validation
Working definitions for this chapter
- Command
- A request for the system to perform an action that changes the state of the system
- A single recipient processes a command
- Sending a command is an asynchronous operation with no return value.
- Event
- Event describes something that has happened in the system, typically as a result of a command
- Multiple subscribers can handle a specific event
- Process manager
- Process manager coordinates the behavior of the aggregates in the domain
- The process manager does not contain any business logic, only logic to determine the next command to send
User stories
- Implement a login using a record locator
- Tell the registrant how much time remains to complete an order
- Enable a registrant to create an order that includes multiple seat types
Architecture
Patterns and concepts
Record locators
The system needs to be able to retrieve order information quickly based on the registrant’s email address and access code
Querying the read side
To minimize the work that the queries on the read side must perform, these SQL views provide a denormalized version of the data
Storing denormalized views in a database
implementing the ViewRepository class
- Using the IQueryable interface
var ordersummary = repository.Query<OrderSummary>().Where(LINQ query to retrieve order summary); var orderdetails = repository.Query<OrderDetails>().Where(LINQ query to retrieve order details);
- Simplicity
- This approach uses a thin abstraction layer over the underlying database
- Testability
- You can use LINQ to Objects for mocking
- Simplicity
- Using non-generic DAOs
var ordersummary = dao.FindAllSummarizedOrders(userId); var orderdetails = dao.GetOrderDetails(orderId); var ordersummary = OrderSummaryDAO.FindAll(userId); var orderdetails = OrderDetailsDAO.Get(orderId);
- Simplicity
- Dependencies are clearer for the client
- Flexibility
- The Get and Find methods hide details
- the partitioning of the data store
- the data access methods such as an object relational mapping
- This makes it easier to change these choices in the future
- The Get and Find methods hide details
- Performance
- You can easily optimize the queries that the Find and Get methods run
- Testability
- It is easier to specify unit tests for the Find and Get methods than to create suitable unit tests for the range of possible LINQ queries that a client could specify
- Maintainability
- All of the queries are defined in the same location, the DAO classes, making it easier to modify the system consistently
- Simplicity
CQRS command validation
- error
- retrying the operation
- business failure
- A business failure should have a predetermined business response
- If the system cannot reserve a seat because there are no seats left, then it should add the request to a wait list