thenativeweb / node-cqrs-eventdenormalizer

Node-cqrs-eventdenormalizer is a node.js module that implements the cqrs pattern. It can be very useful as eventdenormalizer component if you work with (d)ddd, cqrs, domain, host, etc.
http://cqrs.js.org/pages/eventdenormalizer.html
MIT License
38 stars 27 forks source link

Event extenders are not replayed #5

Closed sbiaudet closed 9 years ago

sbiaudet commented 9 years ago

It seems to be that event extenders are not replayed when you call replay function. Could you confirm ?

adrai commented 9 years ago

yes, only viewBuilders are called...

sbiaudet commented 9 years ago

is it possible to replaying event extenders to ? I explain. I've this eventExtender to denormalize a linked aggregate.

I'd like replay old events to migrate my db.

var async = require('async');

module.exports = require('cqrs-eventdenormalizer').defineEventExtender({
  name: 'workitemCreated',
  aggregate: 'workitem',
  context: 'portfolio'
}, function (evt, col, callback) {

  if (evt.payload.portfolioId) {

    this.loadViewModel(evt.aggregate.id, function (err, vm) {
      if (err) {
        debug(err);
        return callback(err);
      }

      var portfolioRepo = col.repository.extend({collectionName: 'portfolio'});

      portfolioRepo.get(evt.payload.portfolioId, function (err, portfolio) {
        var res = {};

        if (portfolio) {
          var obj = portfolio.toJSON();

          res = {
            id: obj.id,
            name: obj.name
          }

          vm.set('portfolio', res);
          vm.commit();
        }

        return callback(null, evt);
      });
    });
  } else {
    return callback(null, evt);
  }

});
adrai commented 9 years ago

this isn't really an event extender, right? Why not making 2 viewbuilders?

adrai commented 9 years ago

ok... I see... but calling the event extenders while replaying will not work correctly, because I cache the vms...

sbiaudet commented 9 years ago

How are you doing in the same situation. I can't do that in viewbuilder, it's not async. I use exclusively event extenders to do that. Perhaps I've not really understand the event extender's essence. How do you use it ?

adrai commented 9 years ago

put all your infos needed, in the event

sbiaudet commented 9 years ago

Yes, but it's ugly.... in DDD and CQRS your aggregate is bounded in his context. In my exemple portfolio and workitem are 2 aggregates root with just a relationship. I've just the portfolioId in my workitem aggregate. But to optimize my read part i use denormalization process to merge related data.

adrai commented 9 years ago

Could it be a valid option for you, if the viewBuilder function would be async? for example:

module.exports = require('cqrs-eventdenormalizer').defineViewBuilder({
  name: 'enteredNewPerson',
  aggregate: 'person',
  context: 'hr',
  version: 2,
  id: 'aggregate.id',
  payload: 'payload'
}, function (data, vm, callback) {
  vm.set('firstname', data.firstname);
  vm.set('lastname', data.lastname);

  var portfolioCol = require('../portfolio/collection');
  // portfolioCol.get(evt.payload.portfolioId, function (err, portfolio) {...

  callback(null);
});
sbiaudet commented 9 years ago

It should be great !!!

But could you explain me how do you use event extenders, I missing something...

adrai commented 9 years ago

event extenders are an optional concept of mine... with them you can extend/manipulate an event (for example with authorization information) after the denormalization...

adrai commented 9 years ago

undocumented feature!!!

adrai commented 9 years ago

@sbiaudet perhaps you're interested in the useAsQuery function https://github.com/adrai/node-cqrs-eventdenormalizer#viewbuilder-for-multiple-viewmodels-in-a-collection

sbiaudet commented 9 years ago

@adrai it's very nice. I like it ;)