NestJS 中的概念及其的多,上手的难度是有点高的,但是学习使我快乐~
控制器的作用
处理:请求和响应
NestJS 是面向切面编程,控制器就是控制层。
控制器在接收到请求之后,会分析请求对象,然后将不同的请求交给不同的路由来处理。
在 NestJS 中面向切面使用的装饰器, @Controller 就是修饰一个 class 为控制器。
装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射(将请求绑定到相应的控制器)。
控制器中路由
- 请求对象 request,
- 修饰符:
@Req - 约束:
import { Request } from 'express';
- 修饰符:
下面是一个完整的列表:
| 装饰器 | http对象 | 说明 |
|---|---|---|
| @Request() | req |
请求对象 |
| @Ip() | req.ip |
ip地址 |
| @Session() | req.session |
响应对象 |
| @Param(key?: string) | req.params / req.params[key] |
请求参数 |
| @Body(key?: string) | req.body / req.body[key] |
请求体 |
| @Query(key?: string) | req.query / req.query[key] |
请求查询 |
| @Headers(name?: string) | req.headers / req.headers[name] |
请求头 |
| @next() | next |
进入下一个 |
| @Response(), @Res()* | res |
响应对象 |
我们看到,在 NestJS 中提供的装饰其中,大多是与请求有关的,方便我们获取请求相关的数据。
这些装饰器全部来自 @nestjs/common 公共这个包里:
import { Controller, Get, Query, Post, Body, Put, Param, Delete } from '@nestjs/common';
请求方法装饰器
| 装饰器 | 说明 |
|---|---|
| @Get | get请求 |
| @Delete | delete请求 |
| @Patch | patch请求 |
| @Options | option请求 |
| @Head | head请求 |
| @All | all请求 |
请求地址
- @Get('/abc'), 如果没有上层文件夹,即
/abc路径 - 字符
?,+,*,和()可在路由路径中使用,并且是其正则表达式的对应的子集。连字符(-)和点(.)由基于字符串的路径逐字解释。
HTTP状态码
- 装饰器:@HttpCode(204), HttpCode 也是赖在
'@nestjs/common'
请求头
- @Header('Cache-Control', 'none'), Header从@nestjs/common包中导入。
路由重定向
- @Redirect('nestjs.com', 301)
子域路由
- 该@Controller装饰可以采取一个host选项,要求进入的请求的HTTP主机相匹配一些特定的值。
@Controller({ host: ':account.example.com' })
export class AccountController {
@Get()
getInfo(@HostParam('account') account: string) {
return account;
}
}
作用域
请记住,Node.js并不遵循请求/响应多线程无状态模型,在该模型中,每个请求都由单独的线程处理。因此,使用单例实例对于我们的应用程序是完全安全的。
但是,在某些情况下,控制器的基于请求的生存期可能是所需的行为,例如GraphQL应用程序中的每个请求缓存,请求跟踪或多租户。在此处了解如何控制范围。
异步
@Get()
async findAll(): Promise<any[]> {
return [];
}
- 基于 rxjs 是的异步更加强大, 但是也更加复杂
@Get()
findAll(): Observable<any[]> {
return of([]);
}
DTO(数据传输对象)架构
对于一个前端而言,可能不是很理解 DTO。
DTO是定义如何通过网络发送数据的对象。
我们可以使用TypeScript接口或简单的类来确定DTO模式。
有趣的是,我们建议在这里使用类。为什么?类是JavaScript ES6标准的一部分,因此,它们在编译的JavaScript中保留为真实实体。
另一方面,由于TypeScript接口是在编译过程中删除的,因此Nest无法在运行时引用它们。这很重要,因为管道等功能在运行时可以访问变量的元类型时,它们还提供了其他可能性。
DTO 其实就是一种类型约束,确保请对象数据是符合我们预期的类型, 但是 DTO 不是 interface,在编译为 TS 会消失,所以必须是个类,所以可以理解为 DTO约束类。
export class CreateCatDto {
name: string;
age: number;
breed: string;
}
CreateCatDto 是具有三个字段的DTO 约束类。约束类主要在路由的处理函数中起到约束作用
// 约束一个请求体
@Post()
create(@Body() createCatDto: CreateCatDto) {
return 'This action adds a new cat';
}
// 约束一个查询对象
@Get()
findAll(@Query() query: ListAllEntities) {
return `This action returns all cats (limit: ${query.limit} items)`;
}
// 约束参数
@Get(':id')
findOne(@Param('id') id: string) {
return `This action returns a #${id} cat`;
}
// 约束参数,请求体
@Put(':id')
update(@Param('id') id: string, @Body() updateCatDto: UpdateCatDto) {
return `This action updates a #${id} cat`;
}
}
放入NestJS中
因为 NestJS 有自己的模块中心,controller 也放入了模块需要的 controllers 字段中。
import { Module } from '@nestjs/common';
import { CatsController } from './cats/cats.controller';
@Module({
controllers: [CatsController],
})
export class AppModule {}