Configuration
forRootAsync
Configure the database connection asynchronously, e.g. from ConfigService.
DrizzleCrudModule.forRootAsync(options) is the asynchronous variant of forRoot. Use it when your configuration is built at runtime — typically read from ConfigService after env validation.
Signature
DrizzleCrudModule.forRootAsync({
imports?: ModuleClass[];
useFactory: (...deps: any[]) => Promise<DrizzleCrudConfig> | DrizzleCrudConfig;
inject?: any[];
}): DynamicModuleExample — with @nestjs/config
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
DrizzleCrudModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (cfg: ConfigService) => ({
dialect: 'postgresql',
connectionString: cfg.getOrThrow<string>('DATABASE_URL'),
schema,
defaults: {
pagination: { defaultLimit: 20, maxLimit: 100 },
},
}),
}),
],
})
export class AppModule {}The useFactory may return a Promise<DrizzleCrudConfig> if you need to read from a remote source (Vault, AWS SSM, etc.) before constructing the config object.
Example — pre-built Drizzle instance with config
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { drizzle } from 'drizzle-orm/postgres-js';
import postgres from 'postgres';
import { DrizzleCrudModule } from 'nestjs-drizzle-crud';
import { schema } from './db/schema';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
DrizzleCrudModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (cfg: ConfigService) => {
const client = postgres(cfg.getOrThrow<string>('DATABASE_URL'));
return {
dialect: 'postgresql',
db: drizzle(client, { schema }),
};
},
}),
],
})
export class AppModule {}Example — multiple injected services
DrizzleCrudModule.forRootAsync({
imports: [ConfigModule, FeatureFlagsModule],
inject: [ConfigService, FeatureFlagsService],
useFactory: (cfg: ConfigService, flags: FeatureFlagsService) => ({
dialect: 'postgresql',
connectionString: cfg.getOrThrow('DATABASE_URL'),
schema,
sql: {
enableFullTextSearch: flags.isEnabled('fts'),
},
}),
})useClass / useExisting
forRootAsync exposes useFactory directly — it does not accept useClass or useExisting. If you need a class-based config, wrap it:
class CrudConfigService {
constructor(private readonly cfg: ConfigService) {}
create() {
return { dialect: 'postgresql' as const, /* ... */ };
}
}
DrizzleCrudModule.forRootAsync({
imports: [ConfigModule],
inject: [CrudConfigService, ConfigService],
useFactory: (svc: CrudConfigService) => svc.create(),
})When to use forRoot vs forRootAsync
Use forRoot when the config object can be built statically at module-evaluation time. Use forRootAsync when any of:
- The connection string is read from
process.envand you want validation viaConfigService. - The Drizzle instance is built from config (e.g. dynamic pool size).
- You depend on another provider in
useFactory(feature flags, secrets manager).