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).