如何在 Nestjs 中创建 mongodb 连接提供程序

dif*_*use 5 mongodb node.js typescript nestjs

我正在尝试在 Nestjs 中为 MongoDB 创建一个数据库连接提供程序。

user.controller.ts通过放置断点检查了mongoDbProvider 并发现控制器在建立数据库连接之前获取。如何在控制器初始化之前建立数据库连接?

Nest.js 文档说 useFactory 方法将在依赖它的任何其他模块之前运行。

src/mongo-db/mongodb.provider.ts

import { MongoClient } from "mongodb";
import { MONGODB_PROVIDER } from "../constants";

export const mongoDbProviders = [
  {
    provide: MONGODB_PROVIDER,
    useFactory: async () => {
      MongoClient.connect('mongodb://localhost:27017',
        { useUnifiedTopology: true },
        (error, client) => {
          return client.db('nestjs-sample');
        });
    }
  },

];
Run Code Online (Sandbox Code Playgroud)

src/mongo-db/mongo-db.module.ts

import { mongoDbProviders } from './mongo-db.providers';

@Module({
  providers: [...mongoDbProviders],
  exports: [...mongoDbProviders],
})
export class MongoDbModule {

}
Run Code Online (Sandbox Code Playgroud)

src/constants.ts

export const MONGODB_PROVIDER = 'MONGODB_CONNECTION';
Run Code Online (Sandbox Code Playgroud)

我导入MongoDbModuleuser.module.ts

src/user/user.module.ts

import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { MongoDbModule } from 'src/mongo-db/mongo-db.module';

@Module({
  imports: [MongoDbModule],
  controllers: [UserController],
  providers: [UserService]
})
export class UserModule {}
Run Code Online (Sandbox Code Playgroud)

在这里,我将dbfrommongoDbProvider注入到UserController构造函数中。但是构造函数在数据库连接之前运行。

src/user/user.controller.ts

import { Controller, Post, Req, Get, Res, Inject } from '@nestjs/common';
import { Request, Response } from "express";
import { MONGODB_PROVIDER } from 'src/constants';

@Controller('users')
export class UserController {

  constructor(@Inject(MONGODB_PROVIDER) private readonly db: any) {

  }

  @Post()
  async create(@Req() request: Request, @Res() response: Response) {
    this.db.collection('users').insertOne(request.body, (err, result) => {
      if (err) {
        response.status(500).json(err);
      } else {
        response.status(201);
        response.send(result);
      }
    });
  }

  @Get()
  get(@Req() request: Request, @Res() response: Response) {
    response.status(400).json({
      message: 'kidilam service'
    });
  }

}
Run Code Online (Sandbox Code Playgroud)

dif*_*use 4

我找到了解决方案。这是因为useFactory期望有一个承诺,因为它是一个async函数。所以我把MongoClient.connect()a包裹在里面Promise来解析数据库连接。现在,它会等到 Promise 解决后再初始化依赖于它的任何模块。

import { MongoClient } from "mongodb";
import { MONGODB_PROVIDER } from "../constants";

export const mongoDbProviders = [
  {
    provide: MONGODB_PROVIDER,
    useFactory: async () => new Promise((resolve, reject) => {
      MongoClient.connect('mongodb://localhost:27017',
      { useUnifiedTopology: true },
      (error, client) => {
        if (error) {
          reject(error);
        } else {
          resolve(client.db('nestjs-sample'));
        }
      });
    })
  },
];
Run Code Online (Sandbox Code Playgroud)