Nest基础概念扫盲

120 阅读4分钟

Nest大纲

  • Nest基础
    • IOC
    • AOP
    • 全局模块
    • 动态模块
    • 自定义provider
    • middleware
    • pipe
    • interceptor
    • guard
  • 中间件
    • Mysql
    • mongodb
    • redis
    • rabbitMQ
    • nacos
    • pm2
    • docker
    • docker compose
  • 实战
    • 会议室预定系统
    • 考试系统
    • 聊天室项目

模块

  • 每个模块包含controller和service.

Controller

  • Controller是处理路由和解析请求参数的(Query Param Body)

Service

  • 业务逻辑的处理, 比如操作数据库,参数校验等。

DTO

  • 封装请求参数的

entities

  • 是包装对应数据库表的是实体的。

Repository

  • 实现对数据库的增删改查

DataSource

  • 数据库连接对象 配置对象config(用户名和密码等)

  • Nest实现了一套依赖注入机制,叫做IOC(控制反转)

    • 简单说就是你只需要声明依赖了啥就行,不需要手动去new依赖,Nest的IOC容器会自动给你创建并注入依赖。(实例会自动注入,只需声明,无需new实现)

    • 后端应用在初始化的时候,需要理清楚依赖的先后关系,创建一大堆对象组合起来,而且不要多次new一直使用一个保持单例模式。这就后端应用的痛点。

    • 之前我们手动创建和组装对象很麻烦,我们能不能再class上声明依赖了啥,然后让工具自己去分析声明依赖关系,根据先后顺序自动把对象创建好了组装起来。

  • IOC的思路:

    • 它有一个放置对象的容器,程序初始化的时候会扫描class上的声明依赖关系。然后把class都new出来一个实例放到容器中。创建对象的时候,还会把他们依赖的对象注入进去。 这样就完成了自动对象创建和组装。这个依赖注入的方式叫做DI.

可被注入的对象

  • @Injectable: AppService这个类可注入,那么nest就会把这个类的对象放到IOC容器中.

  • @Controller: AppController类可被注入, nest也会把它放到IOC容器里。AppController的构造参数依赖了AppService,或者属性进行了声明

  •  import {AppService} from "./app.service"; 
     import {Injectable} from "@nestjs/common";
     @Controller()
     class AppController {
       // 构造器声明
       constructor(private readonly  appService: AppService) {}
       // 属性声明
       @Injectable(AppService)
       private  appService: AppService
     }
    
    • Controller是单独的装饰器?
      • 因为Service是可以被注入也可以注入到别的对象中,所以用@Injectable声明,而Controller只需要被注入,所以nest单独给它加了@Controller装饰器。
  • @Module: 声明模块,其中controllers是控制器,只能被注入,providers里可以被注入,也可以注入别的对象,比如AppService

    •  import {NestFactory} from "@nestjs/core"; 
       import {AppModule} from "./app.module"; 
      async function bootstrap() {
        const app = await NestFactory.create(AppModule)
        app.listen(3000)
      }
      
    • Nest会从AppModule开始解析class上通过装饰器声明依赖关系,自动创建和组装对象。
  • 当generate生成一个模块时,AppModule里会自动imports这个模块,当import别的模块后,那个模块exports的provider就可以在当前模块注入了

  • Nest提供了Module和Module之间的import,可以通过exports引入别的模块的provider来注入

  • Provider的注入方式

// 提供者的声明方式
@Module({
  providers: [
      Appservice,
      {
         provide: "app_service",
         useClass: Appservice
      },
      {
         provide: "person",
         useValue: {
              name: "aaa",
              age: 20
         }
      },
      {
         provide: "person2",
         useFactory() {
           return {
              name: "bbb",
             desc: "cccc"
           }
         }
       }
  ]
})

// 提供者的服务注入方式: 属性注入和构造器注入
 class UserController{
  // 构造器注入
  constructor(private readonly userService: UserService) {}
  // 属性注入
  @Inject(UserService)
  private userService: UserService
 }
  • Nest应用跑起来以后,会从AppModule开始解析,初始化IOC容器,加载所有的service到容器中,然后解析controller里的路由,接下来就可以接受请求了。
  • 跨多个controller的逻辑处理:
    • Nest提供了AOP面向切片编程的机制,具体来说,有Middleware,Guard, Interceptor, Pipe ExceptionFilter五种。他们都是在handler前后,添加一些额外的逻辑。
    • 通用的逻辑通过AOP的方式抽离出来,然后在用的时候在controller中声明一下
       @Get("bbb")
       @UseInterceoptor(TimeInterceptor)
       bbb():string {
         console.log("bbbb...")
         return "bbb";
       }
    
  • 五种数据传递的方式
    • param: 把参数写在url中http://cooper.com/person/111, 111就是路径参数(url param)
    • query: 通过url中?后面用&分隔的字符串传递数据http://cooper.com/person?name=cooper&age=18, 特殊字符的编码需要使用encodeURIComponent或者使用queryString来处理。
    • form-urlencoded: 直接用form表单提交数据,和query字符串的区别在于放在了body里。使用&分割的form-urlencoded方式对内容做urlencoded如果传递大量数据,比如文件上传就不合适了。因为encode会比较慢,这个时候使用formData的方式
    • form-data: 不是通过&连接的,而是用过boundary分隔符实现,因为不是url的方式,不在需要urlEncode,指定的contentType为multipart/form-data.
    • json: 如果只是传递json数据,直接指定contentType为application/json

Nest支持静态服务

  • 使用useStaticAssets来支持静态服务