Projecting event to a legacy schema.

58 views
Skip to first unread message

Tim Needham

unread,
Apr 16, 2014, 12:30:40 PM4/16/14
to ddd...@googlegroups.com
Hi,

I've inherited a large, legacy booking system which I'm re-writing using CQRS. 

By way of preamble, I've built the system such that the aggregates publish their events to a bus.
A set of classes subscribe to the relevant events on that bus and then persist them to the event store.
Another set of projections also subscribe to the events and project the relevant changes onto the legacy database model,

The problem I'm having is that some of the old model objects are interdependent on each other and I need to find a way to 
project them that doesn't rely on the events being fired in a specific sequence. (aka a very bad thing)

The old model objects look something like this

Booking
- List<Item>
- List<Passenger>
- List<Itinerary> 

Item has a property (relative to the booking) called SequenceNumber and the various Passenger and Itinerary objects can be 
associated with a specific Item using their LinkedItemSequenceNumber properties.

My Booking aggregate generates events such as ItemAdded, PassengerAdded and ItineraryAdded when the relevant methods
are called.

An example of my problem is that when my PassengerProjector attempts to project the PassengerAdded event onto the legacy
database, the table being written to has a reference to the primary key of the associated Itinerary entry if there is one.

Obviously the PassengerProjector could use the LinkedItemSequenceNumber and the Id of the booking to hit the legacy database
and retrieve the primary key of the Itinerary entry but that only works if the ItineraryAdded event was projected before the 
PassengerAdded event was projected.

How do I break this dependency? My plan was:

- If the Passenger does not have a LinkedItemSequenceNumber then project it to the database immediately.
- If it does, then query the database to see if the Itinerary object has already been projected.
- If it has then project the Passenger immediately
- If it hasn't then delay the projection of the Passenger until such time as the Itinerary has been projected.

The various projection objects are contained within a service Projector class which could easily provide storage for the delayed
events as well as callbacks for the various Projections delay their events, determine whether any events have been delayed
for their events and trigger the projection of those delayed events.

This plan seems reasonable (if cumbersome) to me but being a CQRS newbie I really can't judge whether it's correct, in the 
spirit of DDD/CQRS or completely insane. The only other choices seem to be to implement gigantic compound events which
basically create (and so project) the entire booking model object in one go.

Thanks,
Tim
Reply all
Reply to author
Forward
0 new messages