[英]Best practice to use config service in NestJS Module
我想使用环境变量来配置每个模块的HttpModule
,从文档中我可以使用这样的配置:
@Module({
imports: [HttpModule.register({
timeout: 5000,
maxRedirects: 5,
})],
})
但是我不知道从环境 vairable(或配置服务)中包含 baseURL 的最佳做法是什么,例如:
@Module({
imports: [HttpModule.register({
baseURL: this.config.get('API_BASE_URL'),
timeout: 5000,
maxRedirects: 5,
})],
this.config
在这里undefined
,因为它不在课堂上。
从环境变量(或配置服务)设置 baseURL 的最佳做法是什么?
HttpModule.registerAsync()
是在 5.5.0 版本中添加的,带有这个pull request 。
HttpModule.registerAsync({
imports:[ConfigModule],
useFactory: async (configService: ConfigService) => ({
baseURL: configService.get('API_BASE_URL'),
timeout: 5000,
maxRedirects: 5,
}),
inject: [ConfigService]
}),
这个问题在这个问题上进行了讨论。 对于像TypeOrmModule
或MongooseModule
这样的 nestjs 模块,实现了以下模式。
useFactory
方法返回配置对象。
TypeOrmModule.forRootAsync({
imports:[ConfigModule],
useFactory: async (configService: ConfigService) => ({
type: configService.getDatabase()
}),
inject: [ConfigService]
}),
虽然卡米尔写道
上述约定现在适用于所有嵌套模块,并将被视为最佳实践(+对第 3 方模块的推荐)。 更多在文档中
它似乎还没有为HttpModule
实现,但也许你可以打开一个关于它的问题。 我上面提到的问题中还有一些其他的建议。
还可以查看官方文档,了解如何实现ConfigService
的最佳实践。
尽管对于大多数实现来说,这个问题的最高评价答案在技术上是正确的,但@nestjs/typeorm
包和TypeOrmModule
的用户应该使用看起来更像下面的实现。
// NestJS expects database types to match a type listed in TypeOrmModuleOptions
import { TypeOrmModuleOptions } from '@nestjs/typeorm/dist/interfaces/typeorm-options.interface';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [mySettingsFactory],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
type: configService.get<TypeOrmModuleOptions>('database.type', {
infer: true, // We also need to infer the type of the database.type variable to make userFactory happy
}),
database: configService.get<string>('database.host'),
entities: [__dirname + '/**/*.entity{.ts,.js}'],
synchronize: true,
logging: true,
}),
inject: [ConfigService],
}),
],
controllers: [],
})
export class AppRoot {
constructor(private connection: Connection) {}
}
这段代码所做的主要事情是从 TypeORM 中检索正确的类型(参见导入)并使用它们来提示返回值 configService.get() 方法。 如果你不使用正确的 TypeORM 类型,Typescript 会发疯的。
我还遇到了实现ConfigService
的几个问题,如 NestJS 文档中所述(没有类型安全性,没有配置值的模块化,...),我在这里非常详细地写下了我们公司的最终 NestJS 配置管理策略: NestJS 配置管理
基本思想是有一个中央配置模块,从进程环境中加载所有配置值。 但是,不是为所有模块提供单一服务,而是每个模块都可以注入配置值的专用子集! 因此,每个模块都包含一个类,该类指定该模块在运行时需要提供的所有配置值。 这同时为开发人员提供了对配置值的类型安全访问(而不是在整个代码库中使用字符串文字)
希望这种模式也适用于您的用例:)
@Kim Kern的好回答,它清楚地将ConfigService
注入模块配置,这可能依赖于环境变量; 然而,根据我的个人经验,你的 app-root 模块或一些其他带有几个导入的模块可能会变得拥挤和/或难以阅读以及理解导入、模块配置和你定义的模块所依赖的内容。 因此,感谢Jay McDoniel为我策划了这个问题, you can move configuration logic into a separate file
中。
app.module.ts
示例:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { MikroOrmModule } from '@mikro-orm/nestjs';
import { AppService } from './users.service';
import { AppController } from './users.controller';
import { get_db_config } from './config/database.config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
expandVariables: true,
}),
MikroOrmModule.forRootAsync( get_db_config() ),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
config/database.config.ts
示例:
import { MikroOrmModuleAsyncOptions } from "@mikro-orm/nestjs";
import { ConfigService } from "@nestjs/config";
export function get_db_config(): MikroOrmModuleAsyncOptions
{
return {
useFactory: (configService: ConfigService) =>
({
dbName: 'driver',
type: 'postgresql',
host: configService.get('DB_HOST'),
port: configService.get('DB_PORT'),
user: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
autoLoadEntities: true
}),
inject: [ConfigService]
}
}
但是, NestJS Docs - Configuration Namespaces以及 NestJS Authentication and Authorization Course 提供了解决此问题的替代方法。
auth.module.ts
示例:
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { JwtModule } from '@nestjs/jwt';
import jwtConfig from './jwt.config';
@Module({
imports: [
ConfigModule.forFeature( jwtConfig ),
JwtModule.registerAsync( jwtConfig.asProvider() ),
]
})
export class AuthModule {}
jwt.config.ts
示例:
import { registerAs } from "@nestjs/config"
export default registerAs('jwt', () => {
return {
secret: process.env.JWT_SECRET,
issuer: process.env.JWT_TOKEN_ISSUER,
accessTokenTtl: parseInt(process.env.JWT_TOKEN_TTL)
};
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.