With event sourcing, you can project an event to create query-optimised read models. This I understand. What I'm unsure about is whether these read models can depend on each other?
I'm considering pre-generating HTML pages and PDF reports in a certain part of an application. The HTML pages are not interactive, but rather information, just like the PDF reports. However, in order to generate the reports, the data needs to be obtained from another projection. Namely, an SQL projection. So the architecture of the application would look at follows:
+-----------+
|Event Store| +------------+
+--^-----+--+ |SQL Database+-------+
| | +------^-----+ |
| | | |
| | | |
+---+-----v---+ +------------+ +----+----+ |
|Command Model+-------->Event Stream+----+---->Projector| |
+-------------+ +------------+ | +---------+ |
| |
| |
| +-------------+ |
+---->HTML Renderer<----+
| +-------------+ | +---------+
| +---------------->+HTML Page|
| | +---------+
| +------------+ |
+---->PDF Renderer<-----+
+------------+ +------------+
+---------------->+PDF Document|
+------------+
The problem with the above is that the HTML Renderer
and PDF Renderer
are dependant on another projection, which means that the order in which the projections are built becomes important. Is this a significant problem?
The alternative to the above is to:
- Treat the HTML/PDF rendering as a query, performed per request.
- Make the HTML and PDF projectors use their own internal data structures (i.e., an SQL table similar to the SQL projector), removing the ordering issue.
- Treat the HTML/PDF rendering as a separate layer "on top of" the query layer. E.g., a query says "give me the objects matching criteria C and format it using formater F". The query gets the data from the database, and the appropriate renderer is used to produce output.