I want to apply CQRS pattern in a project but i don't understand how can i join and denormalize data.
Consider a data model where there are 2 entities: Product and Store in a many to many relationship and an attribute named stock (the product quantity in a particular store) as a relationship attribute.
Consider also that I already created 2 microservices:
At this point, I want to create a third microservice that is responsible to join the data of ProductService and StoreService in order to retrieve all the available products. Here, CQRS pattern seems like the best solution: I will create a materialized view and I will synchronize it using domains events published by the other 2 microservices. Great!
And now the doubts.
Suppose the materialized view has the following columns:
product_sku, product_name, stock, store_name, store_address.
When I update a Product entity or Store entity there is no problem to sync the view because I already have data on it. But what about when I receive a ProductCreated event? This event has only information about product and nothing else, so stock, store_name, store_address will be NULL. How can I save this event in my view? Should i save incomplete data somewhere else and update my view when I will receive complete data?
Thanks!
CQRS , Event sourcing and Materialized view
Your are right, Generally CQRS , materialized view goes with Event sourcing pattern. Which means that we keep on adding our events into event store (this is single point of truth). We generate materialized view by scheduling the job that would read the data from event store and create/update materialized view or we can generate the materialized view following by event trigger. So when you would get store service event (that's probably after product event) then you know that's your last event for particular transaction and query event store to update materialized view and you will have all the data. In short keep dumping in event store and query at once your event store to update your materialized view. Adding event source itself can be complicated so don't over complicated if you can mange without it.
Your case
If you are not using event store then in your case you save the partial/incomplete information in the Materialized view and keep updating it when other inflight events arrive. You will have single reference/key against which you will be updating your data in materialized view. Since the whole system is eventual consistent you will have to manage how would you like to display incomplete (if you have to) data on frontend or you can flag it if you don't want to show (unflag when last event arrives and information is complete).