Event Sourcing (11): Writing JavaScript to Generate Custom Projections in EventStoreDB

Original link: https://teddy-chen-tw.blogspot.com/2022/07/11javascripteventstoredb.html

July 04 18:38~19:46

截圖 2022-07-04 下午6.51.42_thumb[1]

▲Figure 1: User-defined projection program of EventStoreDB

foreword

The previous episode introduced how ezKanbana implements Projector to generate the data required by the Read Model in the PostgreSQL database. This episode uses the customized Projection function of EventStoreDB to create another form of Read Model.

***

Generate event projection through JavaScript program

Teddy introduced the three built-in Projections of EventStoreDB: $all, $ce- and $et- in < Reading Event Sources (6): Querying the Event Store through Projection >. In addition to the built-in Projection, EventStoreDB also supports users to write JavaScript programs to generate Projections. what. JavaScript program? ! That’s right, Teddy wrote it right, and the villagers didn’t read it wrong, it’s a JavaScript program. EventStoreDB can execute JavaScript programs, project the event stream the user wants, and then use this event stream to generate read data.

According to the official document of EventStoreDB, it is an event source database developed for writing, and it is also a database that can be used as a reading model. EventStoreDB can be used as a database for taking models through custom Projection.

Figure 1 shows the JavaScript program used by ezKanban to project all Board events. The fromStreams function in lines 1 to 5 indicates that these event streams are used as input sources. Lines 11 to 13 project all received events into the event stream of another ReplayEvents-By-Board-[board id]. This user-defined event stream can be used as a reading model for ezKanban’s replay function. You can also use this event stream as a data source and pass it to the NotifyBoardContent program in the previous episode <Event Source (10): Implementing Projector>, so that it can instantly project the read model required by GetBoardContent.

The architecture of using EventStoreDB as the reading database is shown in Figure 2. Taking the GetBoardContent query as an example, it will directly read all events belonging to a certain Board from the ReplayEvents-By-Board-[board id] event stream, and then Call NotifyBoardContent to have it replay these events on the fly and project the current state.

截圖 2022-07-04 下午7.06.19_thumb[1]

▲Figure 2: Treat EventStoreDB as Read Database

ezKanban’s GetBoardContent query does not use this method as a source for reading data, but the team has a test case to verify the efficiency of this approach, as shown in Figure 3.

截圖 2022-07-04 下午7.13.25_thumb[2]

▲Figure 3: Use the test case to simulate using EventStoreDB as the read model database for GetBoardContent

***

Efficacy comparison

Du Yixuan, a member of the ezKanban team, in her master thesis “Separation of Command and Query Responsibilities to Simplify Aggregation Dependencies: Taking ezKanban as an Example” compares the use of PostgreSQL database and the JSON read in the previous and <Event Source (10): Implementing Projector> The performance comparison of the model is shown in Figure 4. It can be seen that the greater the number of cards, the greater the benefit of applying CQRS.

截圖 2022-07-04 下午7.18.49_thumb[1]

▲Figure 4: The performance comparison of GetBoardContent query before and after applying CQRS to ezKanban made by Du Yixuan’s master’s thesis

In Du Yixuan’s master’s thesis, the method of using EventStoreDB to build the GetBoardContent reading model introduced in this episode did not compare, but the ezKanban team made an informal comparison in the form of the test case in Figure 3 a few days ago, and the results are as follows:

  • With 8000 cards, it takes about 2179 ms. This speed is still much faster than reading data without establishing (original need 16841 ms).
  • The team further simulated taking 1000 domain events to create a Snapshot as an example, the time to generate GetBoardContent can be shortened to 87ms, which is very close to the 73ms time of generating a read model in JSON format in the PostgreSQL database.

***

Benefits of EventStoreDB Custom Projection

If the architecture introduced in the previous episode <Event Source (10): Implementing Projector> is used to apply CQRS, the Projector on the reading side needs to have the idempotent feature, and if the reading database is damaged, it is necessary to find a way to read the original The domain events of the project re-project the read data (replay). Using EventStoreDB’s custom projection, as long as you write a good JavaScript program, EventStoreDB will be responsible for generating projections, and users don’t have to worry about idempotent issues. As for replay, it is also very simple, because all domain events are stored in the stream projected by EventStoreDB, so just read all the events of the stream from the beginning and apply them one by one. Although the performance of this method is not as fast as storing View Models directly with JSON, if necessary, adding Snapshot can greatly improve the performance of EventStoreDB as a reading database.

As for which method to use to read the CQRS database, it depends on the individual project needs and technical capabilities of the villagers.

***

Next episode preview

The core concepts and technologies of Event Storming and CQRS are almost the same. After the next episode, we will discuss some more advanced topics, starting with helping Aggregate or Read Model to create Snapshots.

***

Youzo’s inner monologue: Write DB can also be Read DB.

This article is reprinted from: https://teddy-chen-tw.blogspot.com/2022/07/11javascripteventstoredb.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment