@nestjs-multitenant/typeorm
v1.0.1
Published
Multi-tenant TypeORM integration for NestJS
Maintainers
Readme
@nestjs-multitenant/typeorm
A simple multi-tenant library for NestJS with TypeORM that manages DataSource instances per tenant.
Features
- Request-scoped tenant resolution
- Per-tenant TypeORM DataSource management
- Automatic connection pooling per DataSource
- Support for different tenant isolation strategies (database-per-tenant, schema-per-tenant)
- Injectable tenant repositories
- Transaction support
Installation
npm install @nestjs-multitenant/typeormQuick Start
1. Implement a Tenant Resolver
import { Injectable } from '@nestjs/common';
import { Request } from 'express';
import { TenantResolver, TenantContext } from '@nestjs-multitenant/typeorm';
@Injectable()
export class HeaderTenantResolver implements TenantResolver {
resolveTenant(request: Request): TenantContext {
const tenantId = request.headers['x-tenant-id'] as string;
if (!tenantId) {
throw new Error('Tenant ID not found in headers');
}
return { tenantId };
}
}2. Implement a Config Provider
import { Injectable } from '@nestjs/common';
import { DataSourceOptions } from 'typeorm';
import { TenantConfigProvider, TenantContext } from '@nestjs-multitenant/typeorm';
@Injectable()
export class DatabasePerTenantConfigProvider implements TenantConfigProvider {
getTenantConfig(context: TenantContext): DataSourceOptions {
return {
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'password',
database: `tenant_${context.tenantId}`,
entities: [User, Product],
synchronize: false,
};
}
}3. Configure the Module
import { Module } from '@nestjs/common';
import { MultiTenantModule } from '@nestjs-multitenant/typeorm';
@Module({
imports: [
MultiTenantModule.forRoot({
tenantResolver: HeaderTenantResolver,
configProvider: DatabasePerTenantConfigProvider,
debug: true,
}),
],
})
export class AppModule {}4. Use in Services
import { Injectable, Inject, Scope } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectTenantRepository, TENANT_REPOSITORY_FACTORY, TenantRepositoryFactory } from '@nestjs-multitenant/typeorm';
import { User } from './user.entity';
@Injectable({ scope: Scope.REQUEST })
export class UserService {
@InjectTenantRepository(User)
private userRepository: Promise<Repository<User>>;
constructor(
@Inject(TENANT_REPOSITORY_FACTORY)
private repositoryFactory: TenantRepositoryFactory,
) {}
async findAll(): Promise<User[]> {
const repo = await this.userRepository;
return repo.find();
}
async createWithTransaction(userData: Partial<User>): Promise<User> {
return this.repositoryFactory.transaction(async (manager) => {
const user = manager.create(User, userData);
return manager.save(user);
});
}
}API Reference
Interfaces
TenantContext- Contains tenant identification informationTenantResolver- Interface for extracting tenant context from requestsTenantConfigProvider- Interface for providing tenant-specific database configurationMultiTenantModuleOptions- Module configuration options
Decorators
@InjectTenantRepository(Entity)- Inject a tenant-specific repository@InjectTenantContext()- Inject the tenant context provider@InjectTenantDataSource()- Inject the tenant data source manager
Services
TenantDataSourceManager- Manages DataSource instances per tenantTenantContextProvider- Request-scoped service holding tenant contextTenantRepositoryFactory- Creates repositories for the current tenant
Examples
See the /examples directory for complete examples including:
- Header-based tenant resolution
- Subdomain-based tenant resolution
- Database-per-tenant configuration
- Schema-per-tenant configuration
License
MIT
