#nestjs #nestjs-config
Вопрос:
Я не могу асинхронно подключиться к mongodb. Пожалуйста, дайте мне знать, что я делаю не так.
Файл MongoConfig:
import { MongooseModuleOptions } from '@nestjs/mongoose';
export default (): { mongoConfig: MongooseModuleOptions } => ({
mongoConfig: {
uri: process.env.DB_URI,
connectionName: 'learn-nest',
useCreateIndex: true,
useUnifiedTopology: true,
useFindAndModify: false,
useNewUrlParser: true,
},
});
Вот код, написанный внутри модуля приложения
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '@nestjs/mongoose';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: ['.env'],
isGlobal: true,
cache: true,
}),
MongooseModule.forRootAsync({
useFactory: (configService: ConfigService): any => {
configService.get('mongoConfig');
},
inject: [ConfigService],
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Это ошибка, которую он выдает:
«Невозможно уничтожить свойство ‘retryAttempts’ из ‘mongooseModuleOptions’, поскольку оно не определено»
Я не понимаю, почему возникает эта ошибка, потому что «retryAttempts» является необязательным свойством в интерфейсе MongooseModuleOptions.
Мангустомодулентерфейс
export interface MongooseModuleOptions extends ConnectOptions, Record<string, any> {
uri?: string;
retryAttempts?: number;
retryDelay?: number;
connectionName?: string;
connectionFactory?: (connection: any, name: string) => any;
}
Ответ №1:
Если вы собираетесь использовать асинхронную конфигурацию MongoDB, перейдите к отдельному классу конфигурации. Я объясню, как:
Создайте новую службу для разрешения конфигурации MongoDB.
mongodb.config.service.ts
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import {
MongooseModuleOptions,
MongooseOptionsFactory,
} from '@nestjs/mongoose';
@Injectable()
export class MongodbConfigService implements MongooseOptionsFactory {
constructor(private readonly configService: ConfigService) {}
//You can retrun promise as well
public createMongooseOptions(): MongooseModuleOptions {
return {
//MONGODB_URL is in .env file
//MONGO_REPL_SET is in .env file
//MONGO_AUTH_SOURCE is in .env file
uri: this.configService.get<string>('MONGODB_URL'),
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
useUnifiedTopology: true,
replicaSet: this.configService.get<string>('MONGO_REPL_SET'),
authSource: this.configService.get<string>('MONGO_AUTH_SOURCE'),
};
}
}
Импорт модуля мангуста :
//...
MongooseModule.forRootAsync({
imports: [ConfigModule],
useClass: MongodbConfigService,
}),
//...
Если вы хотите настроить MongoDB в качестве пространства имен конфигурации :
Создайте файл для хранения конфигурации: mongodb.config.ts
import { registerAs } from '@nestjs/config';
// @returns MongooseModuleOptions
export default registerAs('mongo_db', () => ({
//MONGODB_URL is in .env file
//MONGO_REPL_SET is in .env file
//MONGO_AUTH_SOURCE is in .env file
uri: process.env.MONGODB_URL,
useNewUrlParser: true,
useFindAndModify: false,
useCreateIndex: true,
useUnifiedTopology: true,
replicaSet: process.env.MONGO_REPL_SET,
authSource: process.env.MONGO_AUTH_SOURCE,
}));
Теперь в модуле конфигурации импорт:
import mongoDbConfig from '<path>/mongodb.config';
//...
ConfigModule.forRoot({
envFilePath: ['.env'],
isGlobal: true,
cache: true,
load:[mongoDbConfig]
}),
//...
Импорт модуля мангуста :
//...
MongooseModule.forRootAsync({
useFactory:(configService:ConfigService)=>{
return this.configService.get<MongooseModuleOptions>('mongo_db')
},
inject: [ConfigService],
}),
//...
Оба подхода должны сработать.
Кстати: Набор реплик и источник аутентификации были скопированы из моей конфигурации. игнорируйте его, если у вас нет настройки реплики.
Комментарии:
1. Большое вам спасибо за это замечательное объяснение. Теперь мне ясно, как это работает.
Ответ №2:
Ваш useFactory
ничего не возвращает, так что у вас нет вариантов для MongooseModule
использования. Это было бы похоже на то, чтобы сделать что-то подобное
function getConfig(configService) {
config.get('CONFIG_KEY');
}
const config = getConfig(configServce);
console.log(config) // undefined
Заводская функция не возвращает значение, поэтому она не определена. Вы можете добавить return configServicce.get('mongoConfig')
, и это должно работать так, как ожидалось. Или вы можете заставить функцию анонимной стрелки возвращать объект с помощью () => ({})
. ()
Окружение {}
очень важно для возврата встроенного объекта, в противном случае JS считает, что это тело функции.
Комментарии:
1. Спасибо тебе за внимание, Джей. Я попытался вернуть mongoConfig, но он все равно выдает ту же ошибку.