nestjs搭建通用业务框架(5):数据库+配置

这是《nestjs搭建通用业务框架》系列的第5篇,进入开发具体的功能之前,学习nest框架本身提供的CLI工具与规划合理的工程目录,对于要实现的内容进行架构与计划,这是实现健壮高可用的框架的前提。

技术整合会从三个层次进行介绍:

  • 数据库 -> 配置(多环境) -> 配置验证 -> 系统日志(本篇)
  • 跨域 -> 错误拦截器 -> 缓存Redis
  • 数据校验 -> 日志拦截 -> 鉴权

数据库

ORM工具库

通过数据库集成库或 ORM ,例如 Sequelize (recipe)TypeORM ,以在更高的抽象级别上进行操作。

ORM:对象关系映射(英语:Object Relational Mapping)是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。 从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。

应用场景:

  • SQL -> DB:我们写一套配置,针对不同的数据库,都可以方便的接入
  • DB -> SQL:针对不同的数据库,都可以通过抽象层进行联接

Nest 还提供了与现成的 TypeORM@nestjs/typeorm 的紧密集成,我们将在本章中对此进行介绍,而与 @nestjs/mongoose 的紧密集成将在官方的这一章中介绍

目前主要的ORM工具库与特点:

  • typeorm:跨库查询,事务、TS支持,支持数据库:MySQL, MariaDB, Postgres, CockroachDB, SQLite, MSSQL, Oracle, SAPHana, sql.js, MongoDB
  • objection: TS、事务、饥饿加载、数据效验,基于knexjs,支持数据库:Postgres**, MSSQL, MySQL, MariaDB, SQLite3, **Oracle, Amazon Redshift
  • sequelize: 有非官方的中文文档,目前缺少核心的维护与开发。支持:PostgreSQL, MySQL, MariaDB, SQLite, MSSQL
  • prisma:后起之秀(官方文档写的很不错),SQL自动合并,对接GraphQL,客户端、服务端+数据管理GUI,支持:PostgreSQL, MSSQL, MySQL, SQLite

通过上面的简单对比,目前来看TypeORM是nest官方支持且推荐的,可以来这里看看它的特性。

集成Postgre(MySQL)

步骤:

  • 安装@nestjs/typeormtypeorm
  • 安装nodejs侧的数据库驱动程序,如mysqlpg
  • 新建数据库配置文件,配置数据库
  • app.module.ts引入数据库的配置文件,调用TypeOrmModule.forRoot方法
  • 启动程序,进行测试

安装依赖(跳过数据库安装过程):

1
npm install --save @nestjs/typeorm typeorm pg

按照上面的步骤,创建文件src/config/database.config.ts

数据库配置信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
import { TypeOrmModuleOptions } from '@nestjs/typeorm'

export const typeOrmConfig: TypeOrmModuleOptions = {
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'changeme',
database: 'demo-db',
entities: [`${__dirname}/../entity/**/*.{js,ts}`],
synchronize: false,
logging: ["error"],
}

src/app.module.ts中添加TypeOrm配置:

1
2
3
4
5
6
7
8
9
10
11
12
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { typeOrmConfig } from './config/typeorm.config';


@Module({
imports: [
TypeOrmModule.forRoot(typeOrmConfig)
],
providers: [],
})
export class AppModule {}

然后就可以使用npm run start:dev来进行调试了。

集成MongoDB

非关系型数据库MongoDB同样可以使用TypeORM,官方提供了@nestjs/mongoose包,所以,我们来介绍两种集成方法:

官方@nestjs/mongoose

安装依赖:

1
npm install --save @nestjs/mongoose mongoose

配置app.module.ts

1
2
3
4
5
6
7
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';

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

使用mongoose

安装依赖:

1
npm install --save mongoose

新建src/database/database.providers.ts

1
2
3
4
5
6
7
8
9
import * as mongoose from 'mongoose';

export const databaseProviders = [
{
provide: 'DATABASE_CONNECTION',
useFactory: async (): Promise<typeof mongoose> =>
await mongoose.connect('mongodb://localhost:27017/test'),
},
];

新建src/database/database.module.ts

1
2
3
4
5
6
7
8
import { Module } from '@nestjs/common';
import { databaseProviders } from './database.providers';

@Module({
providers: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule {}

配置app.module.ts

1
2
3
4
5
6
7
8
9
import { Module } from '@nestjs/common';
import { DatabaseModule } from './database/database.module.ts';

@Module({
imports: [
DatabaseModule,
],
})
export class AppModule {}

配置

应用程序通常在不同的环境中运行,根据环境(Development,Production)的不同,应该使用不同的配置设置。

两种方法:

  • 使用@nestjs/config来实现对.envkey=value对进行解析
  • 使用config库解析yaml格式的文件

官方@nestjs/config

最简单的用法

1
npm i --save @nestjs/config

配置src/app.module.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';

@Module({
imports: [
ConfigModule.forRoot(),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

然后创建:.env文件:

1
2
DATABASE_USER=test
DATABASE_PASSWORD=test123

下面来使用src/app.controller.ts中使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Controller, Get } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { AppService } from './app.service';

@Controller()
export class AppController {
constructor(
private readonly appService: AppService,
private configService: ConfigService,
) {}

@Get()
getHello(): string {
const dbUser = this.configService.get<string>('DATABASE_USER');
console.log(dbUser); // 这里来测试
return this.appService.getHello();
}
}

如果访问localhost:3000即可以看到:

1
2
3
4
5
6
7
8
[Nest] 14039   - 2021/03/13 下午9:43:54   [NestFactory] Starting Nest application...
[Nest] 14039 - 2021/03/13 下午9:43:54 [InstanceLoader] ConfigHostModule dependencies initialized +95ms
[Nest] 14039 - 2021/03/13 下午9:43:54 [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 14039 - 2021/03/13 下午9:43:54 [InstanceLoader] AppModule dependencies initialized +1ms
[Nest] 14039 - 2021/03/13 下午9:43:54 [RoutesResolver] AppController {}: +7ms
[Nest] 14039 - 2021/03/13 下午9:43:54 [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 14039 - 2021/03/13 下午9:43:54 [NestApplication] Nest application successfully started +2ms
test

进阶玩法

从这里点进去,我们发现ConfigModuleOptions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import { ConfigFactory } from './config-factory.interface';
export interface ConfigModuleOptions {
cache?: boolean;
isGlobal?: boolean;
ignoreEnvFile?: boolean;
ignoreEnvVars?: boolean;
envFilePath?: string | string[];
encoding?: string;
validate?: (config: Record<string, any>) => Record<string, any>;
validationSchema?: any;
validationOptions?: Record<string, any>;
load?: Array<ConfigFactory>;
expandVariables?: boolean;
}

所支持的参数。

我们可以利用envFilePath配合NODE_ENV来,在不同的启动命令的时候使用不同的配置。

1
npm i cross-env

然后添加两个文件:.env.development.env.production,比如.env.production

1
2
DATABASE_USER=test1
DATABASE_PASSWORD=test123321

下面修改scripts

1
"start:prod": "cross-env NODE_ENV=production node dist/main",

可以设置app.module.ts中默认是development

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';

const envPath = `.env.${process.env.NODE_ENV || 'development'}`;
console.log('🚀 ~ file: app.module.ts ~ line 7 ~ envPath', envPath);

@Module({
imports: [
ConfigModule.forRoot({
envFilePath: envPath,
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

同样,大家可以启动了测试一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
➜ npm run start:prod

> nestjs-common-template@0.0.1 start:prod /Users/macos/Projects/nestjs/nestjs-common-template
> cross-env NODE_ENV=production node dist/main

🚀 ~ file: app.module.ts ~ line 7 ~ envPath .env.production
[Nest] 14977 - 2021/03/13 下午11:10:13 [NestFactory] Starting Nest application...
[Nest] 14977 - 2021/03/13 下午11:10:13 [InstanceLoader] ConfigHostModule dependencies initialized +34ms
[Nest] 14977 - 2021/03/13 下午11:10:13 [InstanceLoader] ConfigModule dependencies initialized +1ms
[Nest] 14977 - 2021/03/13 下午11:10:13 [InstanceLoader] AppModule dependencies initialized +1ms
[Nest] 14977 - 2021/03/13 下午11:10:13 [RoutesResolver] AppController {}: +6ms
[Nest] 14977 - 2021/03/13 下午11:10:13 [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 14977 - 2021/03/13 下午11:10:13 [NestApplication] Nest application successfully started +3ms
test1

上面打印的test1正是我们设置在.env.production中的内容。

解析yaml格式的配置

步骤:

  • 下载js-yaml@types/js-yaml

    1
    2
    npm i js-yaml
    npm i -D @types/js-yaml
  • 创建配置:config.yml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    http:
    host: 'localhost'
    port: 8080

    db:
    postgres:
    url: 'localhost'
    port: 5432
    database: 'yaml-db'

    sqlite:
    database: 'sqlite.db'
  • 配置自定义文件configuration.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    import { readFileSync } from 'fs';
    import * as yaml from 'js-yaml';
    import { join } from 'path';

    const YAML_CONFIG_FILENAME = 'config.yml';
    const filePath = join(__dirname, YAML_CONFIG_FILENAME);

    export default () => {
    return yaml.load(readFileSync(filePath, 'utf8'));
    };

  • 调用forRoot中的load方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { ConfigModule } from '@nestjs/config';
    import Configuration from './config/configuration'; // 这里调整

    @Module({
    imports: [
    ConfigModule.forRoot({
    load: [Configuration], // load方法
    }),
    ],
    controllers: [AppController],
    providers: [AppService],
    })
    export class AppModule {}
  • 修改app.controller.ts中的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import { Controller, Get } from '@nestjs/common';
    import { ConfigService } from '@nestjs/config';
    import { AppService } from './app.service';
    import { DatabaseConfig } from './interface';

    @Controller()
    export class AppController {
    constructor(
    private readonly appService: AppService,
    private configService: ConfigService,
    ) {}

    @Get()
    getHello(): string {
    const db = this.configService.get<DatabaseConfig>('db');
    console.log(db);
    return this.appService.getHello();
    }
    }

    定义src/interface.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    export interface DatabaseConfig {
    postgres: PostgresConfig;
    sqlite: SqliteConfig;
    }

    export interface PostgresConfig {
    url: string;
    port: number;
    database: string;
    }

    export interface SqliteConfig {
    database: string;
    }

最后测试:

1
2
3
4
5
6
7
8
9
10
11
[Nest] 16960   - 2021/03/13 下午11:34:00   [NestFactory] Starting Nest application...
[Nest] 16960 - 2021/03/13 下午11:34:00 [InstanceLoader] ConfigHostModule dependencies initialized +30ms
[Nest] 16960 - 2021/03/13 下午11:34:00 [InstanceLoader] ConfigModule dependencies initialized +0ms
[Nest] 16960 - 2021/03/13 下午11:34:00 [InstanceLoader] AppModule dependencies initialized +0ms
[Nest] 16960 - 2021/03/13 下午11:34:00 [RoutesResolver] AppController {}: +4ms
[Nest] 16960 - 2021/03/13 下午11:34:00 [RouterExplorer] Mapped {, GET} route +3ms
[Nest] 16960 - 2021/03/13 下午11:34:00 [NestApplication] Nest application successfully started +1ms
{
postgres: { url: 'localhost', port: 5432, database: 'yaml-db' },
sqlite: { database: 'sqlite.db' }
}

写到这里,应该够用了,代码可以查看本次提交

使用config库解析

步骤:

  • 安装第三方包config

    1
    2
    npm i config -S
    npm i cross-env -D
  • 新建 配置文件config/default.json,同样还可以建立development.json, production.json

    1
    2
    3
    4
    5
    {
    "server": {
    "happy": "my default value"
    }
    }

    development.json:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "server": {
    "port": 3001,
    "host": "localhost",
    "username": "test",
    "password": "test"
    }
    }

    production.json:

    1
    2
    3
    4
    5
    6
    7
    8
    {
    "server": {
    "port": 3002,
    "host": "localhost",
    "username": "prod",
    "password": "prod"
    }
    }
  • app.controller.ts中使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    import { Controller, Get } from '@nestjs/common';
    import { AppService } from './app.service';
    import * as config from 'config';

    @Controller()
    export class AppController {
    constructor(private readonly appService: AppService) {}

    @Get()
    getHello(): string {
    const server = config.get('server');
    console.log(server);
    return this.appService.getHello();
    }
    }
  • 配置脚本:

    1
    2
    "start:dev": "cross-env NODE_ENV=development nest start --watch",
    "start:prod": "cross-env NODE_ENV=production node dist/main",
  • 运行结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    ➜ npm run start:dev
    [Nest] 34580 - 2021/03/14 上午12:50:42 [NestFactory] Starting Nest application...
    [Nest] 34580 - 2021/03/14 上午12:50:42 [InstanceLoader] AppModule dependencies initialized +34ms
    [Nest] 34580 - 2021/03/14 上午12:50:42 [RoutesResolver] AppController {}: +6ms
    [Nest] 34580 - 2021/03/14 上午12:50:42 [RouterExplorer] Mapped {, GET} route +3ms
    [Nest] 34580 - 2021/03/14 上午12:50:42 [NestApplication] Nest application successfully started +2ms
    {
    happy: 'my default value',
    port: 3001,
    host: 'localhost',
    username: 'test',
    password: 'test'
    }


    ➜ npm run start:prod

    > nestjs-common-template@0.0.1 start:prod /Users/macos/Projects/nestjs/nestjs-common-template
    > cross-env NODE_ENV=production node dist/main

    [Nest] 34400 - 2021/03/14 上午12:50:03 [NestFactory] Starting Nest application...
    [Nest] 34400 - 2021/03/14 上午12:50:03 [InstanceLoader] AppModule dependencies initialized +71ms
    [Nest] 34400 - 2021/03/14 上午12:50:03 [RoutesResolver] AppController {}: +6ms
    [Nest] 34400 - 2021/03/14 上午12:50:03 [RouterExplorer] Mapped {, GET} route +2ms
    [Nest] 34400 - 2021/03/14 上午12:50:03 [NestApplication] Nest application successfully started +2ms
    {
    happy: 'my default value',
    port: 3002,
    host: 'localhost',
    username: 'prod',
    password: 'prod'
    }

    附上:代码地址

配置验证

配置验证,主要是指在应用程序启动时,如果没有提供所需的环境变量或不符合某些验证规则,就会抛出一个异常。@nestjs/config包实现了两种不同的方式来实现这一点。

  • Joi内置验证器。通过Joi,你可以定义一个对象模式,并根据它验证JavaScript对象
  • 一个自定义的validate()函数,它将环境变量作为输入

Joi用法

特别说明:

  • 最新版本的joi需要你运行Node v12或更高版本。旧版本的node请安装v16.1.8。这主要是因为在v17.0.2发布后,在构建的时候会出现错误。更多信息请参考其17.0.0发布说明,点击这里
  • joi最好配合官方的@nestjs/config进行使用

步骤:

  • 安装依赖

    1
    npm install --save joi
  • 定义验证Schema:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import * as Joi from 'joi';
    import { ConfigModule } from '@nestjs/config';

    const envPath = `.env.${process.env.NODE_ENV || 'development'}`;

    @Module({
    imports: [
    ConfigModule.forRoot({
    envFilePath: envPath,
    // 这里多了一个属性:validationSchema
    validationSchema: Joi.object({
    NODE_ENV: Joi.string()
    .valid('development', 'production', 'test', 'provision')
    .default('development'),
    PORT: Joi.number().default(3000),
    DATABASE_USER: Joi.string().required()
    }),
    }),
    ],
    controllers: [AppController],
    providers: [AppService],
    })
    export class AppModule {}

  • 验证测试

    配置错误脚本:

    1
    "start:dev": "cross-env NODE_ENV=development PORT=toimc nest start --watch",

    配置正确的脚本:

    1
    "start:dev": "cross-env NODE_ENV=development PORT=3000 nest start --watch",

    测试命令

    1
    npm run start:dev

    错误的提示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    [下午7:33:38] Found 0 errors. Watching for file changes.

    /Users/macos/Projects/nestjs/nestjs-common-template/node_modules/_@nestjs_config@0.6.3@@nestjs/config/dist/config.module.js:61
    throw new Error(`Config validation error: ${error.message}`);
    ^

    Error: Config validation error: "PORT" must be a number
    at Function.forRoot (/Users/macos/Projects/nestjs/nestjs-common-template/node_modules/_@nestjs_config@0.6.3@@nestjs/config/dist/config.module.js:61:23)
    at Object.<anonymous> (/Users/macos/Projects/nestjs/nestjs-common-template/dist/app.module.js:21:35)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/Users/macos/Projects/nestjs/nestjs-common-template/dist/main.js:4:22)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)

    或者修改.env.development中的配置信息:

    1
    2
    DATABASE_USER=
    DATABASE_PASSWORD=test123

    错误提示:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /Users/macos/Projects/nestjs/nestjs-common-template/node_modules/_@nestjs_config@0.6.3@@nestjs/config/dist/config.module.js:61
    throw new Error(`Config validation error: ${error.message}`);
    ^

    Error: Config validation error: "DATABASE_USER" is not allowed to be empty
    at Function.forRoot (/Users/macos/Projects/nestjs/nestjs-common-template/node_modules/_@nestjs_config@0.6.3@@nestjs/config/dist/config.module.js:61:23)
    at Object.<anonymous> (/Users/macos/Projects/nestjs/nestjs-common-template/dist/app.module.js:21:35)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at Module.require (internal/modules/cjs/loader.js:952:19)
    at require (internal/modules/cjs/helpers.js:88:18)
    at Object.<anonymous> (/Users/macos/Projects/nestjs/nestjs-common-template/dist/main.js:4:22)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)

结论:使用Joi可以很方便对传入应用程序的参数进行验证,可以限制传入的数据类型。

除了上面写的验证以外,还可以加入以下属性来验证输入的命令参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Module({
imports: [
ConfigModule.forRoot({
envFilePath: envPath,
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test', 'provision')
.default('development'),
PORT: Joi.number().default(3000),
DATABASE_USER: Joi.string().required()
}),
validationOptions: { // 这里加
allowUnknown: false,
abortEarly: true,
},
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

@nestjs/config包使用的默认设置是:

  • allowUnknown:控制是否允许在环境变量中使用未知键。默认为true
  • abortEarly:如果为true,则在第一个错误时停止验证;如果为false,则返回所有错误。默认值为false。

注意上面的Joi的用法:

  • 主要是校验process.env传入的参数
  • 主要是校验envFilePath初次加载的时候的参数

使用class-validator

步骤:

  • 安装依赖class-validatorclass-transformer

    1
    npm i class-validator class-transformer
  • 配置效验文件src/env.validation.ts

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    import { plainToClass } from 'class-transformer';
    import { IsEnum, IsNumber, validateSync } from 'class-validator';

    enum Environment {
    Development = "development",
    Production = "production"
    }

    class EnvironmentVariables {
    @IsEnum(Environment)
    NODE_ENV: Environment;

    @IsNumber()
    PORT: number;
    }

    export function validate(config: Record<string, unknown>) {
    const validatedConfig = plainToClass(
    EnvironmentVariables,
    config,
    { enableImplicitConversion: true },
    );
    const errors = validateSync(validatedConfig, { skipMissingProperties: false });

    if (errors.length > 0) {
    throw new Error(errors.toString());
    }
    return validatedConfig;
    }
  • 调整app.module.ts文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    import { Module } from '@nestjs/common';
    import { AppController } from './app.controller';
    import { AppService } from './app.service';
    import { ConfigModule } from '@nestjs/config';
    import { validate } from './env.validation';

    const envPath = `.env.${process.env.NODE_ENV || 'development'}`;

    @Module({
    imports: [
    ConfigModule.forRoot({
    envFilePath: envPath,
    validate,
    }),
    ],
    controllers: [AppController],
    providers: [AppService],
    })
    export class AppModule {}

与使用Joi验证结果一致。

小结

  • 使用第三方的包config,可以方便的读取配置信息,但是校验却需要在读取的位置来加,对于不需要验证,而需要全局使用的配置项可以使用这种方式;

  • 官方的@nestjs/config可以方便的导入.env的文件,同时结合js-yaml也可以导入yaml格式的配置。

    配置灵活,而且可以配合验证工具Joi进行参数的验证(推荐)

    自定义的校验第三方包class-validator这里只是冰山一角,后面在学习数据验证的时候还会使用到它;