Looking for “best practice” advice related to projections:
My teammate is working on a projection that creates a derivative “header” stream for each Widget entity’s stream. This is because Widgets have tons and tons of events but some of the can be considered “header level” and when building a model of a Widget in memory (to, say, execute a command on it), it is often only necessary to scroll through the header-level events.
Here is the projection:
fromCategory(‘widget’)
.when({
“WidgetCreated”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
},
“WidgetAltered”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
},
“WidgetDeleted”: function(state, event) {
linkTo(‘widget.header-’ + event.data.id, event);
}
})
``
So for example, if we have stream named “widget-e8d55c44-d0c7-430d-a187-33e5040fe5c1”, this projection would create a co-stream widget.header-e8d55c44-d0c7-430d-a187-33e5040fe5c1 that would contain only what we deem are header-level events for that widget. So for example we definitely consider WidgetCreated and WidgetDeleted as header events, but not WidgetDoodadTwisted or WidgetThingamabobRecalibrated.
THE PROBLEM
My teammate, in testing and debugging her projection, found it necessary to alter the code and rerun, possibly she also deleted and recreated it under a different name, not sure. I think you can already guess we got the old “Multiple projections emitting to the same stream detected” error.
I know the low-level reason why this is happening, but it’s making me wonder: are we misusing projections? If it’s this difficult to play with projection code until we get it right, and then have a mess of projection-created-but-still-resident streams to deal with?
Right now she just has one single test widget stream, but someday we’ll have hundreds. Impractical to remove all “widget.header-” streams every time we need to fiddle with the projection, just to avoid that error message.
ALTERNATIVE - should we be implementing this “projection” outside Event Store here?
In our Node service that uses Event Store we have event handlers that subscribe to ES streams and populate a query database (standard event sourcing / CQRS here). Should we be using this mechanism to build the “header” streams instead of locking horns with ES here?