NestJS 基础:控制器

1,307 阅读4分钟

NestJS 中的概念及其的多,上手的难度是有点高的,但是学习使我快乐~

控制器的作用

处理:请求和响应

NestJS 是面向切面编程,控制器就是控制层

控制器在接收到请求之后,会分析请求对象,然后将不同的请求交给不同的路由来处理。

在 NestJS 中面向切面使用的装饰器, @Controller 就是修饰一个 class 为控制器。

装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射(将请求绑定到相应的控制器)。

控制器中路由

  1. 请求对象 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请求

请求地址

  1. @Get('/abc'), 如果没有上层文件夹,即/abc路径
  2. 字符?+*,和()可在路由路径中使用,并且是其正则表达式的对应的子集。连字符(-)和点(.)由基于字符串的路径逐字解释。

HTTP状态码

  • 装饰器:@HttpCode(204), HttpCode 也是赖在 '@nestjs/common'

请求头

  • @Header('Cache-Control', 'none'), Header从@nestjs/common包中导入。

路由重定向

子域路由

  • 该@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 {}