Skip to content
微信公众号

NestJS

Nest提供了一个开箱即用的应用程序架构,允许开发人员和团队创建高度可测试、可扩展、松散耦合且易于维护的应用程序。

应用场景

  • 从技术层面上,复杂项目(长期+多子系统)推荐使用
  • 从人力资源层面上,如果中级前端的人数>后端人数可以考虑
  • 从使用成本上说,长期非常香

优缺点

  • 代码架构合理,装饰器语法写起来舒服,但是概念比较多
  • TS原生支持,开发体验好,项目的代码质量高
  • 对于代码人员的要求更高,上手有难度(相比Egg.js/Express/koa)

与其他Node框架相比

  • Koa & Express本身只实现了HTTP服务,中间逻辑需自己实现
  • Egg.js有合理的逻辑分层,但TS支持不好,文档欠缺
  • Nest.js生态最好,使用TS+注解的方式更便捷

资源合集

编程思想

FP

FP(Functional Programming)函数式编程,它是确定的数据输入、输出,没有副作用,相对独立。它引用透明,对IDE友好,易于理解。

OOP

OOP(Object Oriented Programming)面向对象式编程,它是抽象现实生活中事物的特征,对于理解友好。它具有封装性(高内聚、低耦合)、继承性、多态性。

AOP

AOP(Aspect Oriented Programming)面向切面编程,能在不破坏封装功能的前提下,额外增加功能。

它的特点有:

  • 扩展功能方便,不影响业务之间的逻辑
  • 逻辑集中管理
  • 更利于代码复用

nestjs中的管道、过滤器、中间件等都是面向切面编程的实现。

IOC和DI

IOC(Inversion Of Control)控制反转是一种面向对象编程中的一种设计原则,用来减低计算机代码之间的耦合度。其基本思想是:借助于第三方实现具有依赖关系的对象之间的解耦。

DI(Dependency Injection)依赖注入是一种用于实现IOC的设计模式,它允许在类外创建依赖对象,并通过不同的方式将这些对象提供给类。

核心概念

  • Controllers(控制器):负责处理请求、返回响应
  • Services(服务):负责提供方法和操作,只包含业务逻辑
  • Modules(模块):组合所有的逻辑代码
  • Pipes(管道):核验请求的数据
  • Filters(过滤器):处理请求时的错误
  • Guards(守卫):鉴权与认证相关
  • Interceptors(拦截器):给请求与响应加入额外的逻辑
  • Repositories(存储库):负责访问数据库中的数据

Nestjs中使用模块Module来组织应用程序,使用@Module装饰器来描述模块。模块中有4大属性:imports、providers、controllers、exports。

Nestjs将模块分为四大块:功能模块、共享模块、全局模块、动态模块。功能模块与共享模块是一回事,只是叫法不一样。全局模块通常应用在配置、数据库连接、日志上。动态模块是在使用到模块的时候才初始化。

MVC

Nestjs可以通过模板库实现View层,常见:pug、hus、ejs等,Nestjs默认集成express作为web服务器,可以换成koa/fastify。Controller响应前端的请求,Model是对应的具体的数据库逻辑。

DTO(Data Transfer Object)数据传输对象,例如前端请求到后端这是一个传输的过程,后端访问数据库又是一个传输的过程。Nestjs中的DTO约定了数据字段、属性,方便数据校验。

DAO(Data Access Object)数据访问对象,它是一层逻辑:包含实体类、数据库操作(CURD)、数据校验、错误处理等,Nestjs做了一层更高级的封装,通过ORM库与各种类型数据库对接,而这些ORM库就是DAO层。

生命周期

接口服务

官方CLI

官方的CLI是一个命令行界面工具,以帮助您初始化、开发和维护Nest应用程序。它以多种方式提供帮助,包括搭建项目、以开发模式为其提供服务,以及为生产分发构建和打包应用程序。它体现了最佳实践的架构模式,以构建良好的应用程序。

安装

首先全局安装nest cli脚手架,然后通过脚手架来创建项目

shell
npm i -g @nestjs/cli
nest new project-name

工程目录

为了去理解Python的语言设计之美,其实更要理解这样的一句话"约定大于配置",好的工程化目录(约定)能够很好的提升项目的可维护性。

作者推荐

在官方的issues中,我们可以找到一些提示:Best scalable project structure这里有作者的回复。

js
- src
  - core
  - common
    - middleware
    - interceptors
    - guards
  - user
      - interceptors (scoped interceptors)
    - user.controller.ts
    - user.model.ts
  - store
    - store.controller.ts
    - store.model.ts
  • 可以使用monorepo的方法一一在一个repo中创建两个项目,并在他们之间共享共同的东西,如库/包。
  • 没有模块目录,按照功能进行划分。
  • 把通用/核心的东西归为单独的目录:common,比如:拦截器/守卫/管道

参考项目

  1. nestjs-sequelize-typescript

技术栈:Nest + sequelize-typescript + JWT + jest + Swagger

特点:

  • 项目文档及相关的资源在根目录
  • 数据库及项目配置会放在根目录
  • src中会对功能进行划分,建不同的文件夹users、posts
  • 单个功能文件夹中,会包括一个完整的CURD的相关文件(dto/controller/module/providers/service)
  • 抽离公共配置到shared文件夹
  1. nodepress

特点:

  • 项目文档及相关的资源在根目录
  • src中modules会对功能进行划分建不同的文件夹
  • 单个功能文件夹中,会包括一个完整的CURD的相关文件(dto/controller/module/providers/service)
  • 把公共的代码(按照nestjs逻辑分层)拆成单独的文件夹guards、filters、decorators、interceptors、interfaces、errors
  1. nestjs-project-structure

特点:

  • 项目文档及相关的资源在根目录,包括typings、test、bin
  • src中会对功能进行划分建不同的文件夹
  • 抽离公共代码到common文件夹,配置文件放在config文件件,实体类放置在entity中
  • 鉴权相关的逻辑放在auth
  • 把同类的guards、filters、decorators、interceptors、interfaces、errors存放在common文件夹中

核心部分

通过后端框架核心部分主要包括开发层面、功能层面、接口安全层面思考要做哪些内容。

例如从开发层面我们要考虑多环境配置,功能层面考虑通用模块:用户、菜单、权限、日志,最后是接口文档、接口请求安全&性能等。

多环境配置

在行业内应用广泛使用的dotenvconfig

官方提供了@nestjs/config模块:

shell
pnpm i --save @nestjs/config

然后配置src/app.module.ts

ts
import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';
import { ConfigModule } from '@nestjs/config';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
    }),
    UserModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

然后在项目根目录下创建.env文件,编写环境配置。然后在Controller中进行使用。

ts
import { Controller, Get } from '@nestjs/common';
import { UserService } from './user.service';
import { ConfigService } from '@nestjs/config';

@Controller('user')
export class UserController {
  constructor(
    private readonly userService: UserService,
    private readonly configService: ConfigService,
  ) {}

  @Get()
  public getUser() {
    const db = this.configService.get('DB');
    console.log(db);
    return this.userService.getUser();
  }
}

如果我们想使用yaml配置的话,安装js-yaml和@types/js-yaml。

配置验证

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

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

Joi用法

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

安装依赖

shell
npm install --save joi

定义验证schema

ts
import { Module } from '@nestjs/common';
import { UserModule } from './user/user.module';
import { ConfigModule } from '@nestjs/config';
import configuration from './configuration';
import * as joi from 'joi';

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

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      //envFilePath,
      load: [configuration],
      validationSchema:joi.object({
        DB_PORT: joi.number.default(3306)
      })
    }),
    UserModule,
  ],
  controllers: [],
  providers: [],
})
export class AppModule {}

ORM

ORM(Object Relational Mapping)对象关系映射,其主要作用是在编程中,把面向对象的概念跟数据库中的概念对应起来。

例如:定义一个对象,那就对应着一张表,这个对象的实例,就对应着表中的一条记录。

ORM特点:

  • 方便维护:数据模型定义在同一个地方,利于重构
  • 代码量少、对接多种库:代码逻辑更易懂
  • 工具多,自动化能力强:数据库删除关联数据、事务操作等

在nestjs中官方提供了一个非常好用的ORM模块叫TypeORM。具体的可以查看官方文档https://typeorm.io/,中文文档地址为https://typeorm.bootcss.com/

shell
npm install --save @nestjs/typeorm typeorm mysql2

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

ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'root',
      database: 'test',
      entities: [],
      synchronize: true,
    }),
  ],
})
export class AppModule {}

日志

日志等级主要分为以下几种:

  • Log:通用日志,按需进行记录(打印)
  • Warning:警告日志,比如:尝试多次进行数据库操作
  • Error:严重日志,比如:数据库异常
  • Debug:调试日志,比如:加载数据日志
  • Verbose:详细日志,所有的操作与详细信息(非必要不打印)

按照功能分为以下几类:

  • 错误日志:方便定位问题,给用户友好的提示
  • 调试日志:方便开发
  • 请求日志:记录敏感行为

日志记录位置:

  • 控制台日志:在开发时方便查看
  • 文件日志:方便回溯与追踪(24小时滚动)
  • 数据库日志:敏感操作、敏感数据记录

本站总访问量次,本站总访客数人次
Released under the MIT License.