Skip to content

88

大概图解

plaintext
src/
├── config/                 # 配置文件目录
│   ├── database.config.ts
│   ├── jwt.config.ts
│   └── app.config.ts

├── modules/               # 业务模块目录
│   ├── users/            # 用户模块
│   │   ├── dto/         # 数据传输对象
│   │   ├── entities/    # 数据库实体
│   │   ├── interfaces/  # 接口定义
│   │   ├── users.controller.ts
│   │   ├── users.service.ts
│   │   ├── users.module.ts
│   │   └── users.repository.ts
│   │
│   └── auth/            # 认证模块
│       ├── dto/
│       ├── strategies/   # 认证策略
│       ├── guards/      # 守卫
│       ├── auth.controller.ts
│       ├── auth.service.ts
│       └── auth.module.ts

├── common/              # 公共代码目录
│   ├── decorators/     # 自定义装饰器
│   ├── filters/        # 异常过滤器
│   ├── guards/         # 全局守卫
│   ├── interceptors/   # 拦截器
│   ├── middlewares/    # 中间件
│   └── pipes/          # 管道

├── shared/             # 共享模块目录
│   ├── services/       # 共享服务
│   └── utils/         # 工具函数

├── database/           # 数据库相关
│   ├── migrations/     # 数据库迁移文件
│   └── seeds/         # 数据库种子文件

├── app.module.ts       # 应用程序根模块
├── app.controller.ts   # 应用程序根控制器
├── app.service.ts      # 应用程序根服务
└── main.ts            # 应用程序入口文件

test/                  # 测试目录
├── e2e/              # 端到端测试
└── unit/             # 单元测试

├── .env              # 环境变量文件
├── .env.development
├── .env.production
├── package.json
├── tsconfig.json
├── nest-cli.json
└── README.md

Module

每个模块都会包含 controller、service、module、dto、entities 这些东西

controller 是处理路由,解析请求参数的。

service 是处理业务逻辑的,比如操作数据库。

dto 是封装请求参数的。

entities 是封装对应数据库表的实体的。

Controllers && Services

对于某个Module来说,Controllers是接收请求的入口,Services则是方法实现

img

Provider

Controllers是如何调用Services的呢?

  • 当Services成为Provider时**

Import

typescript
// pokemon.module.ts

// 推荐
@Module({
  controllers: [PokemonController],
  providers: [PokemonService],
  imports: [PrismaModule],
  exports: [PokemonService],
})
// 不推荐
@Module({
  controllers: [PokemonController],
  providers: [PokemonService, PrismaService],
  imports: [],
  exports: [PokemonService],
})

Import vs Provider

区别在于:import module会复用已经创建的实例,而每个provider都会创建新的实例。

前者占用更少的内存,且一个可复用的实例在多处被使用在需求中也更加常见。

Summary

看一个Nestjs应用就是看明白Module之间是如何互相作用的。

  • 定义自己的controllers
  • 定义自己的service
  • 把自己的service放在providers中,这样controllers才能用service
  • 如果需要用外部的service,将外部module放在imports里
  • 如果自己的service也需要被其他module使用,将自己的service放到exports里

生命周期

Nest 从接收到请求,到返回响应的这个流程,有很多切面,路由最终是在 cotnroller 的方法,也就是 handler 里处理的。

在 main.ts 里调用 NestFactory.create 方法,就会从 AppModule 开始递归解析 Module,实例化其中的 provider、controller,并依次调用它们的 onModuleInit 生命周期方法。

之后会再递归调用每个 Module 的 provider、controller 的还有 Module 自身的 onApplicationBootstrap 生命周期方法。

Nest 销毁的时候,也会依次调用 Module 的 provider、controller 还有 Module 自己的 onModuleDestroy 方法、beforeApplicationShutdown 还有 onApplicationShutdown 的生命周期方法。

img


文章参考