thenativeweb / node-cqrs-saga

Node-cqrs-saga is a node.js module that helps to implement the sagas in cqrs. It can be very useful as domain component if you work with (d)ddd, cqrs, eventdenormalizer, host, etc.
http://cqrs.js.org/pages/saga.html
MIT License
61 stars 16 forks source link

Saga handlers may be synchronous or return Promises instead of using callbacks #41

Open IRT-fbachmann opened 7 years ago

adrai commented 7 years ago

Thanks for your valueable PRs... But for these cqrs modules I don't want to support Promises... at least not in this major version 😉 I would design the whole thing a bit differently... But thanks anyway...

OrH commented 6 years ago

Is there a specific reason to not support Promises? Is it a wrong design or something?

nanov commented 6 years ago

I guess the reason is compatibility with older node versions, and general design of the current library version.

Is there any specific reason to support those ? No one stops you from implanting an async ( sugar for Promise ) saga handler, and calling commit when done.

Also, the sagas require you to call saga.commit(callback); at the end.

Side note: we are currently developing an on-top library exactly for those cases, when one would like to use modern node features. It is in early stages, and documentation is missing, but it could serve you as an example how one could implement own solutions on top of this library.

OrH commented 6 years ago

Ok, I needed to get some data from a denormalizer in a saga for enriching the next command, but currently it's not possible because the saga handler can't be async. Or maybe you have another approach for this?

BTW, The cqrs-swissknife library seems very interesting!

EDIT: just to clarify - It's possible to create a promise and call the commit within the promise as you mentioned, but my intention was for using async await =]

nanov commented 6 years ago

Something like this:


const { promisify } = require('util');
const myCollection = require('../path/to/my/collection');
const myCollectionFind = promisify(myCollection.find.bind(myCollection));

require('cqrs-saga').defineSaga({
    name: 'myEvent',
    aggregate: 'myAgg',
    context: 'myCtx',
    id: 'aggregate.id',
}, async (event, saga, callback) => {
    const otherReadModels = await myCollectionFind({ my: 'rule' });
    otherReadModels.forEach(rm => saga.addCommandToSend({ name: 'notify', id: rm.id }));

    return saga.commit(callback);
});
OrH commented 6 years ago

I actually tried it, and thought it was blocking the other Sagas from running, but I must have done something wrong because I tried it again now and it works perfect!

Thanks!