NestJS Request Scoped Multitenancy for Multiple Databases

余生长醉 提交于 2020-06-11 06:15:39

问题


Looking to implement a multi-tenant NestJS solution using the new request injection scope feature of NestJS 6.

For any given service I assume I could do something like this:

@Injectable({scope: Scope.REQUEST})
export class ReportService implements OnModuleInit { ... }

then, in the constructor, determine the tenant from the request, connect to the appropriate database, and instantiate repositories for the new connection.

I'm wondering if this is the most straightforward way to go about it?

Instead of updating each service, is it possible to override the connection provider and scope that to the request?


回答1:


Here's what we ended up doing...

  1. Create a simple, global TenancyModule bound to the request scope:

tenancy.module.ts

import { Global, Module, Scope } from '@nestjs/common';
import { REQUEST } from '@nestjs/core';
import { getConnection } from 'typeorm';

const connectionFactory = {
  provide: 'CONNECTION',
  scope: Scope.REQUEST,
  useFactory: (req) => {
    const tenant = someMethodToDetermineTenantFromHost(req.headers.host);
    return getConnection(tenant);
  },
  inject: [REQUEST],
};

@Global()
@Module({
  providers: [connectionFactory],
  exports: ['CONNECTION'],
})
export class TenancyModule {}
  1. Inject request-specific 'CONNECTION' into module services from which to retrieve repositories:

user.service.ts

...
@Injectable({scope: Scope.REQUEST})
export class UserService {
  private readonly userRepository: Repository<User>;

  constructor(@Inject('CONNECTION') connection) {
    this.userRepository = connection.getRepository(User);
  }



回答2:


I would recommend to use the approach by @nurikabe with a request scoped factory provider and request scoped services. Nestjs itself has a similar factory example in the docs.

But for the sake of completenes, there is also another approach: You could also use a middleware and attach the connection to the request object as described in this answer to a similar question. However, attaching things like a connection to the request via a middleware is circumventing the DI mechanism and alienates the request object by making it behave like a service container that delivers the connection – therefore the factory approach should be preferred.



来源:https://stackoverflow.com/questions/56583231/nestjs-request-scoped-multitenancy-for-multiple-databases

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!