非常教程

Nest参考手册

技术

Mongo数据库

有两种方法可以处理 MongoDB 数据库。您可以使用提供 MongoDB 支持的 ORM,也可以使用最受欢迎的 MongoDB 对象建模工具 Mongoose 。如果您想使用 ORM,可以按照以下步骤操作。否则,我们将使用专用包。@nestjs/mongoose

首先,我们需要安装所有必需的依赖项:

$ npm install --save @nestjs/mongoose mongoose

安装过程完成后,我们可以将其MongooseModule导入到根目录中ApplicationModule

app.module.ts

JS

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

@Module({
  imports: [MongooseModule.forRoot('mongodb://localhost/nest')],
})
export class ApplicationModule {}

forRoot()方法接受相同的配置对象作为mongoose.connect()从猫鼬包。

模型注射

使用Mongoose,一切都来自Schema。让我们来定义CatSchema

猫/模式/ cat.schema.ts

JS

import * as mongoose from 'mongoose';

export const CatSchema = new mongoose.Schema({
  name: String,
  age: Number,
  breed: String,
});

CatsSchema属于cats目录。这个目录代表了CatsModule。这是您决定保留架构文件的决定。从我们的角度来看,在相应的模块目录中,最好的方法是将它们保存在几乎所有的域中

我们来看看CatsModule

猫/ cats.module.ts

JS

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { CatSchema } from './schemas/cat.schema';

@Module({
  imports: [MongooseModule.forFeature([{ name: 'Cat', schema: CatSchema }])],
  controllers: [CatsController],
  providers: [CatsService],
})
export class CatsModule {}

该模块使用forFeature()方法来定义哪些模型应在当前范围内注册。多亏了这一点,我们可以注入CatModel的到CatsService用的@InjectModel()装饰:

猫/ cats.service.ts

JS

import { Model } from 'mongoose';
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Cat } from './interfaces/cat.interface';
import { CreateCatDto } from './dto/create-cat.dto';

@Injectable()
export class CatsService {
  constructor(@InjectModel('Cat') private readonly catModel: Model<Cat>) {}

  async create(createCatDto: CreateCatDto): Promise<Cat> {
    const createdCat = new this.catModel(createCatDto);
    return await createdCat.save();
  }

  async findAll(): Promise<Cat[]> {
    return await this.catModel.find().exec();
  }
}

测试

在单元测试我们的应用程序时,我们通常希望避免任何数据库连接,使我们的测试套件独立并尽可能快地执行它们。但是我们的类可能依赖于从连接实例中提取的模型。那是什么?解决方案是创建假模型。为了实现这一点,我们应该设置自定义提供程序。实际上,每个注册的模型都由NameModeltoken表示,其中Name是模型的名称。

@nestjs/mongoose包公开了getModelToken()基于给定模型名称返回准备好的令牌的函数。

@Module({
  providers: [
    CatsService,
    {
      provide: getModelToken('Cat'),
      useValue: catModel,
    },
  ],
})
export class CatsModule {}

现在硬编码catModel将被用作Model<Cat>。每当任何提供者要求Model<Cat>使用@InjectModel()装饰器时,Nest将使用注册的catModel对象。

异步配置

通常,您可能希望异步传递模块选项,而不是事先传递它们。在这种情况下,使用forRootAsync()方法,提供了几种处理异步数据的方法。

第一种可能的方法是使用工厂功能:

MongooseModule.forRootAsync({
  useFactory: () => ({
    uri: 'mongodb://localhost/nest',
  }),
})

显然,我们的工厂表现得像其他每一个(可能async并且能够通过注入依赖关系inject)。

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useFactory: async (configService: ConfigService) => ({
    uri: configService.getString('MONGODB_URI'),
  }),
  inject: [ConfigService],
})

或者,您可以使用类而不是工厂。

MongooseModule.forRootAsync({
  useClass: MongooseConfigService,
})

上面的构造将MongooseConfigService在内部实例化MongooseModule,并将利用它来创建选项对象。在MongooseConfigService必须实现MongooseOptionsFactory的接口。

@Injectable()
class MongooseConfigService implements MongooseOptionsFactory {
  createMongooseOptions(): MongooseModuleOptions {
    return {
      uri: 'mongodb://localhost/nest',
    };
  }
}

为了防止MongooseConfigService内部创建MongooseModule并使用从不同模块导入的提供程序,您可以使用useExisting语法。

MongooseModule.forRootAsync({
  imports: [ConfigModule],
  useExisting: ConfigService,
})

它的作用useClass与一个关键区别相同 - MongooseModule将查找导入的模块以重新使用已创建的ConfigService,而不是单独实例化它。

Nest

Nest 是一个用于构建高效,可扩展的 Node.js 服务器端应用程序的框架

Nest目录

1.介绍
2.常见问题
3.CLI
4.方法
5.执行上下文
6.微服务
7.WEBSOCKETS
8.GRAPHQL
9.技术
10.基本内容
11.迁移指南