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装饰器。
- 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
- param: 把参数写在url中
Nest支持静态服务
- 使用useStaticAssets来支持静态服务