As a small snapshot of my product, I have 2 bounded contexts, one which is a rich domain with defined events and invariants, operating on files implemented as CQRS/ES, and the other a CRUD store of corresponding files and data that will be used as a Customer/Supplier relationship with other exclusive contexts in the product.

For my UI, I would like to query across the two, and so far I have built a read model using the event stream to repopulate a database, but would also like to retrieve some information from the CRUD context. As the domain events don't contain all the information needed for queries (such as file size, additional data, and incidental information which is not required in the rich domain model) how would one approach denormalising the information?

At the moment, the entities reference the file store using a UUID, and when the event is denormalised, I query the file store to get the relevant additional information and create a local copy. I am expecting to also subscribe to any events issued from the CRUD store to update the local read-model at a later date.

My question here is whether this approach is appropriate, and what other proven implementations are for creating a projection from multiple contexts of differing infrastructure?

2 Answers 2


From what I can tell you are doing it right.

Your entities reference other remote entities using IDs, which is the preferred way of inter-aggregate referencing.

You are using events to propagate changes, which is the preferred way.

The only thing you should pay attention to is to make sure that the readmodels' rebuilding does not have side effects.

From my experience the UI comes almost always with requirements that cross Aggregates and even Bounded contexts. CQRS helps by allowing us to have readmodels based on the read use-cases, and write models (Aggregates) based on write use-cases.

  • Awesome, thats good news. From what I can tell, there is no hard and fast way to do it, so it often is a case-by-case decision. One thing that I hypothetically discovered was consistency during rebuild of a read model, and that the two aggregates may be vastly inconsistent due to the nature of the replay event stream. Would it make sense to defer the query of external data until the stream has been fully replayed? Oct 8, 2018 at 5:01
  • @DanielPark just to be sure, what do you mean by inconsistent Aggregates? Oct 8, 2018 at 5:11
  • In a temporal sense; i.e: the event currently being projected was at an earlier time to what the current CRUD context is at. I guess it is a bit of a moot point, as the projection should catch up to what is current in any case. Oct 8, 2018 at 5:22
  • @DanielPark yes, the streams may be out of sync but I noticed that only on a bad designed system is this thing impossible to repair. For example, when a readentity needs data from two Aggregates, one Aggregate gives the ID and the other some other quantitative properties or a nested value object that it can be initially empty. In your case, you may use an empty File, with size 0, empty additional data etc, but with valid ID and you replace this with up-to-date information when the event from the files BC comes. Oct 8, 2018 at 5:37
  • @DanielPark regarding your question, yes, you may defer the query to external data. It makes sense to do this when the external data may have many intermediate states but you are interested only in the final state; CRUD systems are usually like that with many update events that overwrite the data. Oct 8, 2018 at 5:40

In my opinion, it would be less complex to have one read model for each Bounded Context and combine them somehow in the UI.

BCs are solid business delineations - it is not always so natural or easy to query across them. A counterexample would be BI/reporting but it doesn't seem to be the case of the UI you're building.

  • This is my current approach, where I load my query dataset into memory, (by a set of ID's) and execute from there. It seems to be performant enough for the short-term, but ideally would need to look into extending the read model to include cached data from other contexts as to improve performance if it becomes an issue. Nov 8, 2018 at 3:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.