TriPSs / nestjs-query

Easy CRUD for GraphQL.
https://tripss.github.io/nestjs-query/
MIT License
157 stars 43 forks source link

Implement schema based multi tenancy #251

Closed piyushhanchate closed 6 months ago

piyushhanchate commented 6 months ago

I've been trying to implement schema based multi tenancy using this guide, it requires me to inject a custom request scoped connection in the services. Could you help me out with implementing this, please?

TriPSs commented 6 months ago

I have no experience with multi tenancy.

GP4cK commented 6 months ago

We managed to get it to work by doing this:

Step 1: Create a `TypeOrmConfigService` that extends `TypeOrmOptionsFactory` in which you inject the request to extract the tenant id. ```ts import { Inject, Injectable } from '@nestjs/common'; import { DataSource, DataSourceOptions } from 'typeorm'; import { REQUEST } from '@nestjs/core'; import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm'; import type { Request } from 'express'; @Injectable() export class TypeOrmConfigService implements TypeOrmOptionsFactory { private databaseID: string; constructor(@Inject(REQUEST) readonly req: Request ) { this.databaseID = /* Extract the databaseID/tenantID from the request */; } createTypeOrmOptions(): TypeOrmModuleOptions { return { ...yourBaseOrmConfig, database: this.databaseID, }; } static async getOrCreateDataSource(options?: DataSourceOptions): Promise { /** Create and initialize the DataSource here. */ } } ```
Step 2: in your `app.module.ts`, use TypeOrm.forRootAsync with the service you created. ```ts import { Module, NestModule } from "@nestjs/common"; import { TypeOrmModule } from "@nestjs/typeorm"; import { TypeOrmConfigService } from "./config/TypeORMConfig.service"; @Module({ imports: [ TypeOrmModule.forRootAsync({ useClass: TypeOrmConfigService, dataSourceFactory: (options) => TypeOrmConfigService.getOrCreateDataSource(options), }), // Other imports ], }) export class AppModule implements NestModule {} ```

And you should be good to go. Now when you inject a repository in your services with @InjectRepository(), they automatically become request-scoped and use the right connection.