thenativeweb / cqrs-sample

CQRS, EventSourcing, (DDDD) Sample in node.js
148 stars 50 forks source link

Microservices arhitecture #19

Open smariussorin opened 8 years ago

smariussorin commented 8 years ago

Hello, this is a great example of how to use CQRS and Event Sourcing. I was wondering if i use different domains, a single host (the web application) can i achieve a Microservices Architecture? The documentation is good, but i feel it has more power and i want to use them into a Microservice Architecture. Can you give some advice?

adrai commented 8 years ago

...these libs are actually beeing used for bigger microservice arcitectures... with tens of hosts, denormalizers, sagas and domains... ;-)

smariussorin commented 8 years ago

As expected, thanks for your reply. I`ll try to dive more into the documentation to see the bigger picture.

smariussorin commented 8 years ago

Can i inject in a saga the viewmodel module? I need to query the data on a specific event to emit specific commands. I`m doing it wrong? The main idea is to implement a transaction involving multiple entities. The only way i achieved this was on host process, on a command observe, but it seems coupled. Thanks

adrai commented 8 years ago

no problem...

for example bootstrap it like that:

const pm = require('cqrs-saga')({/**/});

const denormalizer = require('cqrs-eventdenormalizer')({/**/});

// register command handlers
pm.on('command', (cmd) => {
  hub.emit('command', cmd);
});

// ...
myhub.on('event', (evt) => {
  denormalizer.handle(evt, (errs) => {
    if (errs) {
      console.error(errs);
    }
  });
});

// ...

denormalizer.defaultEventExtension((evt, callback) => {
  pm.handle(evt, (err) => {
    callback(err, evt);
  });
});

// ...

then you can just require the collection from within the saga handler i.e.:

const myCol = require('../viewBuilders/myEntity/collection');
myCol. loadViewModel('id', (err, vm) => {});
smariussorin commented 8 years ago

Thanks a lot.

smariussorin commented 8 years ago

One question, in this example, the aggregateId is payload.id, i tried to change it to aggregate.id, in all the files, but the edit and the delete failed, i`m missing something? And the context failed the same. I look on https://github.com/pawarvijay/sample-with-context-and-saga-implemented but no success.

adrai commented 8 years ago

here too? https://github.com/adrai/cqrs-sample/blob/master/domain/server.js#L27

adrai commented 8 years ago

do you have it on github somewhere?

smariussorin commented 8 years ago

yes, here the aggregate id is: aggregateId: 'payload.id'. I read some of your issues on github and you recommand to always send the aggregate id

smariussorin commented 8 years ago

https://github.com/smariussorin/EventSourcedMicroservices my repo

smariussorin commented 8 years ago

Or it is ok to send the payload.id as aggregateId? Im a C# developer and this is my first node project and im trying to develop for school a microservice event sourced arhitecture

adrai commented 8 years ago

it should work if you change https://github.com/smariussorin/EventSourcedMicroservices/blob/master/config/saga-config.js#L4 https://github.com/smariussorin/EventSourcedMicroservices/blob/master/config/common-config.js#L19 https://github.com/smariussorin/EventSourcedMicroservices/blob/master/config/common-config.js#L27 to aggregateId: 'aggregate.id'

and then adapt this stuff: https://github.com/smariussorin/EventSourcedMicroservices/blob/master/host/public/js/accounts-app.js#L127

to something like:

             var cmd = new Backbone.CQRS.Command({
                id:_.uniqueId('msg'),
                command: 'deleteAccount',
                aggregate: { 
                    id: accountId
                },
                meta: "smarius.sorin@yahoo.com"
            });

PS. it is just your choice how you want to structure the message... ;-) -it doesnt't really matter

smariussorin commented 8 years ago

Ok, and if i want to add the aggregateName and context, i need to add them in all the places. Do i need to specifi the context and aggregate name in https://github.com/smariussorin/EventSourcedMicroservices/blob/master/host/public/js/accounts-app.js#L127, or they will be automated fill?

Example: Do i need to change the https://github.com/smariussorin/EventSourcedMicroservices/blob/master/domain-account/lib/changeAccount.json to define the structure to include aggregate name and context?

adrai commented 8 years ago

1) yes, no automated fill... no magic... 2) if you want to

smariussorin commented 8 years ago

Thanks for your answers and time.

smariussorin commented 8 years ago

One minor question about domain: if i need to add created_at field in create events, where is the best way to init this date? i don`t want to send the client date, i want to do it in domain flux. Thanks.

adrai commented 8 years ago

There s already a feature for this: https://github.com/adrai/node-cqrs-domain#define-the-event-structure commitStamp

If this is not exactly what you want you have to add the the date in each handle for the commands https://github.com/adrai/node-cqrs-domain#command

smariussorin commented 8 years ago

Ok thanks, i already use commitStamp, but as i seen is more like a updated_at field. I needed additional field and i didn`t know where is the right place to do this.

smariussorin commented 8 years ago

When i`m finished, i will push a example with Angular CQRS. It was hard, but i finally did it. Maybe will help others.

adrai commented 8 years ago

Very cool! So I can reference it somewhere :-)

Il giorno 12-giu-2016, alle ore 18:31, Marius Sorin Stratulat notifications@github.com<mailto:notifications@github.com> ha scritto:

When i`m finished, i will push a example with Angular CQRS. It was hard, but i finally did it. Maybe will help others.

You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/adrai/cqrs-sample/issues/19#issuecomment-225446844, or mute the threadhttps://github.com/notifications/unsubscribe/ABCS8l-4oZumG_Z4JmlNElQveBhcN6fHks5qLDWfgaJpZM4IkspU.

smariussorin commented 8 years ago

I pushed the Angular CQRS. https://github.com/smariussorin/EventSourcedMicroservices. I manually added the lib of angular CQRS so i can i further modifications. The behavior of getting the collection is disabled, i use my own behavior.

Example how to set: -main settings \host\public\scripts\app.js -example controller host\public\scripts\controllers\categories.js

I need to add a busy behavior, in 2 weeks most is a full working example

smariussorin commented 8 years ago

One minor question: on my saga, when i add a comand to a saga to send, i have the this error, but the command is send succesfully. I tried to add id generator, but it is optional. image

adrai commented 8 years ago

How does this saga looks like?

Il giorno 13-giu-2016, alle ore 22:45, Marius Sorin Stratulat notifications@github.com<mailto:notifications@github.com> ha scritto:

One minor question: on my saga, when i add a comand to a saga to send, i have the this error, but the command is send succesfully. I tried to add id generator, but it is optional. [image]https://cloud.githubusercontent.com/assets/3168023/16022631/78551e48-31c1-11e6-9c6b-93b1fb176582.png

You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/adrai/cqrs-sample/issues/19#issuecomment-225704122, or mute the threadhttps://github.com/notifications/unsubscribe/ABCS8oZtIg0ICuDQbAMLJY3uaH35Iky_ks5qLcJxgaJpZM4IkspU.

smariussorin commented 8 years ago

I push on https://github.com/smariussorin/EventSourcedMicroservices. Saga-category, on sagas/categoryDeleted.

smariussorin commented 8 years ago

And one minor question: viewmodel/eventdenormalizer find method can be used to search in a property of type array? For example: i need to iterate in order.products[x].id. I wanted to avoid getting all the data.

adrai commented 8 years ago

Try to move saga.commit(callback); 2 lines above

for findViewmodels() yes, but it depends on the db implementation i.e. for mongodb it's ok

Il giorno 13-giu-2016, alle ore 23:17, Marius Sorin Stratulat notifications@github.com<mailto:notifications@github.com> ha scritto:

I push on https://github.com/smariussorin/EventSourcedMicroservices. Saga-category, on sagas/categoryDeleted.

You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://github.com/adrai/cqrs-sample/issues/19#issuecomment-225712807, or mute the threadhttps://github.com/notifications/unsubscribe/ABCS8kSyACTs4JhPDCyyRZuDcIarwiMjks5qLcolgaJpZM4IkspU.

smariussorin commented 8 years ago

for findViewmodels() for mongodb can you give an example? i didn`t find in the example.

smariussorin commented 8 years ago

for saga error: saga.commit(callback): to added it next after addCommandToSend?

adrai commented 8 years ago

findViewModels: this is absolutely ok: https://github.com/smariussorin/EventSourcedMicroservices/blob/master/saga-category/sagas/categoryDeleted.js#L11

saga.commit should be moved between line 25 and 26: https://github.com/smariussorin/EventSourcedMicroservices/blob/master/saga-category/sagas/categoryDeleted.js#L25

smariussorin commented 8 years ago

Thanks. Fixed saga. For the findViewModel i need for https://github.com/smariussorin/EventSourcedMicroservices/blob/master/saga-product/sagas/productDeleted.js. I currently get all data and filter in-memory, and i wanted to get the filter data if possible.

adrai commented 8 years ago

try

ordersRepo.findViewModels({
  'products.id': productId
}, (err, orders) => { ...
adrai commented 8 years ago

like mongodb queries

smariussorin commented 8 years ago

Thanks. I`m finished with my project, thanks for all the time and help.

adrai commented 8 years ago

You're welcome :-)