I have two databases: a master database, which serves as a common database, and another database (dedicated to each tenant/customer) with the same schema. If you have experience with a multi-database approach, this setup should be familiar to you.
Currently, I create a new connection for each request like this:
async getDbConnForUser() {
// Retrieve user from request context
const user = this.utilityService.getUserFromRequestContext();
if (!user) throw new UnauthorizedException('Invalid User');
subdomain = user.subdomain;
// Fetch all subdomains the user has access to
const userSubdomains = await this.tenantService.findUserAndSubdomainsByEmail(user.email);
if (userSubdomains.length === 0) throw new UnauthorizedException('Invalid User');
if (!userSubdomains.find(ud => ud.subdomain === user.subdomain)) {
// This should never occur!
throw new UnauthorizedException('Forbidden Access');
}
const tenant = await this.tenantService.getMasterTenantBySubdomain(subdomain);
if (!tenant) throw new NotFoundException('Tenant not found');
const newDataSource = new DataSource({
type: 'postgres',
host: this.configService.get('TENANT_DB_HOST'),
port: this.configService.get('DB_PORT'),
username: this.configService.get('TENANT_DB_USERNAME'),
password: this.configService.get('TENANT_DB_PASSWORD'),
database: tenant.dbName,
entities: [join(process.cwd(), 'dist/**/tenant/*.entity.js')],
subscribers: [join(process.cwd(), 'dist/**/subscribers/*.subscriber.js')],
synchronize: true // To be removed in production
});
await newDataSource.initialize();
return newDataSource;
}
For example, I use this method to retrieve tenant-specific data in my service as follows:
async getDivisionsByCompany(companyId: number) {
const dataSource = await this.databaseService.getDbConnForUser();
const divisionRepo = dataSource.getRepository(Division);
const divisions = await divisionRepo.find({
where: { companyId: companyId, isActive: true },
});
return divisions;
}
I'm seeking advice on whether this approach is optimal, as it establishes a new connection for each request. Are there better ways to handle multi-tenant databases without creating a new connection each time? Any insights or recommendations would be greatly appreciated.
Datasourceto avoid create new connection. But I have question that What is injections scope ofdatabaseService,DEFAULT,REQUESTorTRASISENT?Datasourcefor each database by name.@Injectableso don't worry about scope. But be careful withREQUESTscope, it will create every providers inject it for each. It make your request more slow.