Advanced
Multitenancy

Multitenancy

Ocoda Event Sourcing provides built-in support for multitenancy. This allows you to separate the event- and snapshot-streams of different tenants. This can be achieved by using pools. A pool is a collection of streams that belong to the same tenant. By default the event- and snapshot-store create a shared collection of streams for all tenants. To enable multitenancy you need to:

Disable the creation of a default pool in the store configuration

  @Module({
      imports: [
          EventSourcingModule.forRoot({
              events: Events,
              eventStore: {
                  driver: InMemoryEventStore,
                  useDefaultPool: false,
              },
              snapshotStore: {
                  driver: InMemorySnapshotStore,
                  useDefaultPool: false,
              },
          }),
      ]
  })
  export class AppModule {}

Create a pool for each tenant

The ensureCollection methods are used to create a pool for a tenant. The pool is created if it does not exist.

  await eventStore.ensureCollection('tenant-1');
  await snapshotStore.ensureCollection('tenant-1');
ℹ️

This library makes a distinction between the types for pools and for collections:

  • a pool (IEventPool and ISnapshotPool) only represents the name of a tenant, e.g. tenant-1
  • a collection (IEventCollection and ISnapshotCollection) is an internal type that represents the name of the collection within the database, e.g. tenant-1-events and tenant-1-snapshots.

Provide a pool when interacting with the event-store or snapshot-repository

  await this.eventStore.appendEvents(stream, account.version, events, 'tenant-1');
  await this.accountSnapshotRepository.save(accountId, account, 'tenant-1');
  await this.accountSnapshotRepository.load(accountId, 'tenant-1');