0

I'm trying to implement Multi-tenancy application which will have the collection of org details, and the org data will be stored in different databases. Like, enter image description here

When someone do the API call, I'll be adding x-org-id header which will send the org ID which is database name.

I have 2 modules

  1. Org Details
  2. Users

I've added database connection at the app.module.ts as below

@Module({
  imports: [
    MongooseModule.forRoot(process.env.DB),
    OrgModule,
    UserModule
  ],
  controllers: [],
  providers: [],
})

process.env.DB will have the master database connection something like mongodb://localhost/my_master_db. When the org is created, I'll be saving the data in my_master_db database in org_details collection. From here, I'll get the _id which is generated by MongoDB and use that as database name for saving the users.

all org related APIs will be in http://localost:3000/org endpoint. here I want to connect to my_master_db.

All the users related API endpoints will be in http://localost:3000/user, and here I want to change the database connection to mongodb://localhost2/{org_id} from the API request header x-org-id.

I've tried THIS solution, By creating a service which uses Scope.REQUEST Injector, it looks like its not working. When I use it on app.module.ts It works, but when I import it on user.module.ts, it wont work.

My mongoose.service.ts file is as below

import { Inject, Injectable, Scope } from '@nestjs/common';
import { MongooseOptionsFactory, MongooseModuleOptions } from '@nestjs/mongoose';
import { REQUEST } from '@nestjs/core';
import { Request } from '@nestjs/common';

@Injectable({ scope: Scope.REQUEST })
export class MongooseConfigService implements MongooseOptionsFactory {
    constructor(
        @Inject(REQUEST) private readonly request: Request) {
            console.log("Injected", "Injected");
    }

    createMongooseOptions(): MongooseModuleOptions {
        return {
             uri: this.request.headers['x-org-id'],
        };
    }
}

My db.module.ts file is as below

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { MongooseConfigService } from './mognoose.service';

@Module({
    imports: [
        MongooseModule.forRootAsync({
            useClass: MongooseConfigService,
        }),
    ]
})
export class DbModule {}

And I'm importing the DbModule to my UserModule as below

@Module({
  imports: [
    MongooseModule.forFeature([{ name: "users", schema: UserModel}]),
    HrmDbModule,
  ],
  controllers: [UserController],
  providers: [UserProvider]
})

How do I fix the issue? What's the best way to connect to Different Databases on the router level?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
rakcode
  • 2,256
  • 4
  • 19
  • 44

1 Answers1

0

Try to check https://github.com/needle-innovision/nestjs-tenancy

Ready solution with tenant id(from header)/subdomain implementation.

No Graphql support (20 Dec 22).

Elmatsidis Paul
  • 385
  • 1
  • 7
  • 19