title: NestJS : database connection (TypeORM) by request (subdomain)
body: <p>I'm trying to build a SAAS product over Nest/TypeORM and I need to configure/change database connection by subdomain.</p>
  
  <pre><code>customer1.domain.com =&gt; connect to customer1 database
  customer2.domain.com =&gt; connect to customer2 database
  x.domain.com =&gt; connect to x database
  </code></pre>
  
  <p>How can I do that ? With interceptors or request-context (or Zone.js) ?</p>
  
  <p>I don't know how to start. Is someone already do that ?</p>
  
  <hr>
  
  <p>WIP : what I am currently doing :</p>
  
  <ol>
  <li>add all connections settings into ormconfig file</li>
  <li><p>create Middleware on all routes to inject subdomain into <code>res.locals</code> (instance name) and create/warn typeorm connection</p>
  
  <pre><code>import { Injectable, NestMiddleware, MiddlewareFunction } from '@nestjs/common';
  import { getConnection, createConnection } from "typeorm";
  
  @Injectable()
  export class DatabaseMiddleware implements NestMiddleware {
      resolve(): MiddlewareFunction {
        return async (req, res, next) =&gt; {
            const instance = req.headers.host.split('.')[0]
            res.locals.instance = instance
  
            try {
                getConnection(instance)
            } catch (error) {
                await createConnection(instance)
            }
  
            next();
        };
      }
  }
  </code></pre></li>
  <li><p>in Controller : get instance name from @Response and pass it to my Service</p>
  
  <pre><code>@Controller('/catalog/categories')
  export class CategoryController {
      constructor(private categoryService: CategoryService) {}
  
      @Get()
      async getList(@Query() query: SearchCategoryDto, @Response() response): Promise&lt;Category[]&gt; {
        return response.send(
          await this.categoryService.findAll(response.locals.instance, query)
        )
      }
  </code></pre></li>
  <li><p>in Service : get TypeORM Manager for given instance and query database through Repository</p>
  
  <pre><code>@Injectable()
  export class CategoryService {
    // constructor(
    //   @InjectRepository(Category) private readonly categoryRepository: Repository&lt;Category&gt;
    // ) {}
  
    async getRepository(instance: string): Promise&lt;Repository&lt;Category&gt;&gt; {
        return (await getManager(instance)).getRepository(Category)
    }
  
    async findAll(instance: string, dto: SearchCategoryDto): Promise&lt;Category[]&gt; {
      let queryBuilder = (await this.getRepository(instance)).createQueryBuilder('category')
  
      if (dto.name) {
          queryBuilder.andWhere("category.name like :name", { name: `%${dto.name}%` })
      }
  
      return await queryBuilder.getMany();
    }
  </code></pre></li>
  </ol>
  
  <p>It seems to work but I not sure about pretty much everything :</p>
  
  <ul>
  <li>connections poole (how many can I create connections into my ConnectionManager ?)</li>
  <li>pass subdomain into response.locals... bad practice ?</li>
  <li>readability / comprehension / adding lot of additional code...</li>
  <li>side effects : I'm afraid to share connections between several subdomains</li>
  <li>side effects : performance</li>
  </ul>
  
  <p>It's not a pleasure to deals with response.send() + Promise + await(s) + pass subdomain everywhere...</p>
  
  <p>Is there a way to get subdomain directly into my Service ?</p>
  
  <p>Is there a way to get correct subdomain Connection/Repository directly into my Service and Inject it into my Controller ?</p>