juicycleff / nestjs-event-store

NestJS CQRS module for EventStore.org. It requires @nestjs/cqrs
https://xraph.com
MIT License
199 stars 29 forks source link

Multiple Feature Registrations in One App Module #17

Open natersgonnanate opened 4 years ago

natersgonnanate commented 4 years ago

Hi, I'm running into an issue registering the EventStoreModule within each domain module of my application. Events are publishing to Event Store, but regardless of module is publishing the event, the stream name is always the first module that's imported in the app.module.ts.

Users Domain Module:

@Module({
    imports: [
        CqrsModule,
        EventStoreModule.registerFeature({
            type: 'event-store',
            featureStreamName: '$svc-identity-user',
            eventHandlers: {
                UserCreatedEvent: (user: UserCreatedPayload) => new UserCreatedEvent(user),
            },
            subscriptions: []
        }),
        MongooseModule.forFeature([{ name: UserDto.name, schema: UserSchema }], connectionName),
        forwardRef(() => AuthModule),
    ],
    providers: [
        UserResolver,
        ...QueryHandlers,
        ...CommandHandlers,
        UsersService,
    ],
    exports: [
        UsersService,
    ],
})
export class UsersModule { }

Organizations Domain Module

@Module({
  imports: [
    CqrsModule,
    EventStoreModule.registerFeature({
      type: 'event-store',
      featureStreamName: '$svc-identity-organization',
      eventHandlers: {
        OrganizationCreatedEvent: (payload: OrganizationCreatedPayload) => new OrganizationCreatedEvent(payload),
        OrganizationUpdatedEvent: (payload: OrganizationUpdatedPayload) => new OrganizationUpdatedEvent(payload),
      },
      subscriptions: []
    }),
    MongooseModule.forFeature([{ name: OrganizationDto.name, schema: OrganizationSchema }], connectionName),
    UsersModule,
  ],
  providers: [
    OrganizationsResolver,
    ...QueryHandlers,
    ...CommandHandlers,
    OrganizationsService
  ],
  exports: [
    OrganizationsService
  ],
})
export class OrganizationsModule { }

App Module

const modules = [
  UsersModule,
  OrganizationsModule,
  AuthModule,
  PluginsModule,
];

const graphQlConfig = GraphQLModule.forRoot({
  include: [...modules],
  debug: process.env.ENVIRONMENT === 'local',
  playground: process.env.ENVIRONMENT === 'local',
  autoSchemaFile: true,
  context: ({ req }) => ({ req }),
});

@Module({
  imports: [
    MongooseModule.forRoot(connString, {
      connectionName: connectionName,
      dbName: dbName,
      useNewUrlParser: true,
      useUnifiedTopology: true,
      readPreference: ReadPreference.SECONDARY_PREFERRED,
    }),
    EventStoreModule.register({
      type: 'event-store',
      tcpEndpoint: {
        host: process.env.EVENT_STORE_HOSTNAME,
        port: +process.env.EVENT_STORE_PORT,
      },
      options: {
        maxRetries: 10,
        maxReconnections: 10,
        reconnectionDelay: 1000,
        heartbeatInterval: 5000,
        heartbeatTimeout: 1000,
        defaultUserCredentials: {
          password: process.env.EVENT_STORE_PASSWORD,
          username: process.env.EVENT_STORE_USERNAME,
        },
      },
    }),
    ...modules,
    graphQlConfig,
  ],
  providers: [
    AuthStartResolver,
    AuthCompleteResolver,
    GlobalExceptionFilter,
  ],
})
export class AppModule {
  async onModuleInit() { }
}

Regardless of the type of event that occurs, everything is being published to Event Store in the $svc-identity-user stream, but if I were to change the orders of the modules imported within the AppModule so that the OrganizationsModule was imported first then everything would publish to the $svc-identity-organization stream.

I may be misunderstanding the feature registrations and/or eventHandlers within each registration but ideally I'll be able to publish different streams per microservice, and similarly then subscribe to those different streams within my other microservices (as well as register and publish events the same way in those microservices). Any guidance would be greatly appreciated.

artalat commented 2 years ago

Running into this issue myself, did you ever find a work around to this?