Reputation: 13
I have a question regarding event sourcing in a microservice architecture.
Suppose that every service stores its own events in a own eventstore, how can i rebuild a read model if the projection needs data from more than one service?
For example we have the UserService and an InvoiceService. In the invoice service model I work only with the user id, but in the read model I need also the user name for easier queryings.
I thank i have now these options:
Did I miss something? Does someone know a easier solution?
Upvotes: 1
Views: 1699
Reputation: 2542
I agree that option 1 is unwise. A domain model (the update model in CQRS, not the read model) should only have primary key pointers into other domains, not supporting data from those domains.
Option 2 is better but still not quite there. I’m not a fan of API calls between domains when using Event Sourcing because it can cause one domain to fail or appear slow due to the difficulties in the second. In your example having the Invoice domain call an API on the User domain to get the username for a read model rebuild means that if the User domain is down the Invoice domain cannot complete its rebuild – the Invoice domain fails through no fault of its own.
Consider option 3 of caching the User information in the Invoice domain. Create listeners to appropriate User events in the Invoice domain and cache the necessary user data there – in this case just the primary key and the username, but you can add more fields later if necessary. Your Invoice read model is then rebuilt using this cache so there is no dependency on the User domain.
Just a clarifying note to make sure we’re all on the same page, and for those readers who are new to CQRS. The Invoice read model should have the userid and username in it, but the domain model should only have the userid. Read models have duplicated information everywhere and are not intended to be third normal form; they are meant to be very fast and contain all information that will be displayed on the screen.
Upvotes: 1
Reputation: 191
Suppose that every service stores its own events in a own eventstore, how can i rebuild a read model if the projection needs data from more than one service?
I think you missed the concept of eventstore. Service should not have its own eventstore. Imagine you are publishing an event from your service and some other services will have to subscribe to your event stream. Your eventstore is the single source of truth for all services.
In this way, if you need to create a projection from multiple streams, then you can do that. Please have a look into this blog post.
Now what if you don't want to build projections on eventstore side. Suppose, you have a new requirement to show a report of users containing a invoice count, total bill etc. Then I would do the following -
Subscribe to listen UserCreated, UserBasicInfoUpdated events from UserService(new subscription)
Subscribe to listen InvoiceGenerated event from InvoiceService(new subscription)
Build the new read model
Then merge previous subscription(if any) into the new one. This is important. Because you should not have multiple subscribers to the same events.
Upvotes: 0
Reputation: 5140
Users can have more than one invoice and replaying/ rebuilding model from event source with the only username won't be ideal (or at least from my understanding). The route I prefer is to have a co-relation identifier
. As the name suggests, it shall help you to build a co-relation between service calls/event sourcing records which took place as part of a given business task/action. Having something to co-relate on is important when it comes to re-building model (whether to show in dashboard or logic to perform model/action replay). From a quick search, I found a talk about co-relation id. Please go-ahead and read more about it and see whether this approach solve your business problem.
Upvotes: 0