NestJS 的 Controller 学习

Controller 介绍

Controller 的作用主要是接受处理请求和向客户端返回处理后的响应数据。在 Controller 中会包含很多的路由,而路由主要是执行不同的业务逻辑处理。

路由

我们在编写 Controller 的时候,可以使用@Controller()装饰器来定义对应的 Controller。在装饰器中我们可以使用路径前缀来为路由分组,从而最大限度地减少重复代码。例如我们可以把商品信息管理的相关路由都放在一个控制器里面,具体代码如下:

import { Controller, Get, Post } from "@nestjs/common";

@Controller("commodity")
export class CommodityController {
  @Get()
  getCommodity(): string {
    return "获取商品";
  }

  @Post("/save")
  saveCommodity(): string {
    return "保存商品";
  }
}

在上述的代码中,我们声明了commodity为前缀的控制器,所以 NestJs 在帮我们生成路由的时候都会在路由地址最前面加上commodity关键字。

而具体路由生成是根据控制器代码块里面的请求装饰器来决定的,就比如上述的代码来说,我们声明了两个接收请求的方法,一个是Get请求,并且采用默认路由方式,而另外是Post请求,并且声明了具体路径地址/save

所以 NestJs 会帮我生产如下两个请求路径:GET /commodityPOST /commodity/save。这样我们向这两个地址发送请求的时候,理由都会走到这两个路由中做后续的业务逻辑处理。

这样我们就可以知道 NestJs 的路径生产规则是:前缀 + 具体路径

注意:在 NestJS 中,采用 NestJs 内置的请求方法时需要注意 POST 的状态码是 201,其他的状态码都是 200。

请求对象

处理程序通常需要访问客户端发送过来的请求数据,而 NestJs 提供对底层平台(默认为 Express)的请求对象的访问,而要使用的时候我们可以使用@Req装饰器来获取对象。具体代码如下:

@Get()
getCommodityList(@Req() request: Request): string {
  return '获取商品列表'
}

注意:在上述代码中我们使用了 Request 对象,而这个对象在 NestJS 中是没有对这个对象的声明,所以需要我们安装@types/express。

Request 这个对象里面有很多的信息,例如有请求的 HTTP 标头、正文、参数等等。在大部分情况下我们不用手动获取这些属性,因为 NestJS 帮我门写好了对应的装饰器。具体的装饰器如下表:

装饰器 对应对象和属性
@Request(), @Req() request 对象
@Response(), @Res()* response 对象
@Next() next 对象
@Session() request 对象中的 session 属性
@Param(key?: string) request 对象中的 params 对象
@Body(key?: string) request 对象的 body 对象
@Query(key?: string) request 对象中的 query 对象
@Headers(name?: string) request 对象中的 headers 对象
@Ip() request 对象中的 IP 信息 属性
@HostParam() request 对象中的主机信息属性

注意:在 NestJs 中,程序响应处理它已经帮我们做好了处理,我们只要直接返回数据就可以而无需做什么特殊处理,假如你在方法中注入了@Req()或者@Response(),就相当于将 Nest 置于某个特殊平台的模式下,这样响应就需要你自己进行处理,即必须通过调用对象 response(res.json()或者 res.send())来发出响应,否则 HTTP 服务器将会挂起。

路由通配符

在 NestJs 中提供了标准的 HTTP 方法的装饰器:@Get()@Post()@Put()@Delete()@Patch()@Options()@Head()

在路由通配符中字符 ?、+、* 和 () 是其正则表达式同应项的子集。

通配符的具体例子如下:

// 匹配/random.text的请求路径
@Get('/random.text')
getTextInfo() {
  return '获取text文件'
}

// 匹配geinfo和getinfo的请求路径,即t字符允许出现一次或没有
@Get('/get?info')
getInfo() {
  return '?通配符'
}

// 匹配getabc或者gettabc的请求路径,即t字符最少出现一次和出现多次
@Get('/get+abc')
getAbc() {
  return '+通配符'
}

// 匹配/abe 和 /abcde
@Get('/ab(cd)?e')
getAbcd() {
  return '()通配符'
}

// 匹配以get开头的所有请求路径
@Get('/get*')
getCommodityList(@Req() request: Request): string {
  return '*通配符'
}

在通配符中*通配符的匹配深度是最大的,所以在使用*通配符的时候最好放在最后一个,因为在 NestJs 中路由是由上而下进行匹配的。

状态码

如前所述,默认情况下响应状态代码始终为 200,POST 请求除外,该代码为 201。在 NestJS 中我们可以使用@HttpCode()装饰器来设置状态码。

设置响应头

在 NestJs 中我们想要自定义响应头的话可以使用@Header()装饰器或者使用响应对象来进行设置。具体代码如下:

@Put()
@Header('Cache-Control', 'none')
updateCommodity(): string { return '修改商品' }

重定向

在 NestJs 中我们可以使用@Redirect()装饰器来实现重定向到具体的 URL 上。我们也可以使用响应对象来实现重定向的功能。

其中@Redirect()装饰器可以接受两个参数,一个是重定向的 URL,另外一个是响应的状态码。

有时候我们重定向的地址是根据有些参数判断后进行动态跳转的,我们只要这样做就可以。

@Get('search')
@Redirect('https://biyinig.com', 302)
getSearch(@Query('searchType') version: string) {
  if (version && version === 'baidu') {
    return { url: 'https://www.baidu.com' };
  }
}

子域路由(需要验证)

@Controller装饰器可以接受指定路由作为参数外,还可以接收host对象来声明其他的主机地址,作为真实的请求地址。具体的实例如下:

@Controller({ host: "admin.example.com" })
export class AdminController {
  @Get()
  index(): string {
    return "Admin page";
  }
}

启动和运行

当我们声明好控制器以后,NestJs 仍然不知道该控制器的 CatsController 存在,因此不会创建此类的实例。

所以我们可以在AppModule中添加我们声明的控制器。具体代码如下:

import { CommodityController } from "./controller/commodity.controller";
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";

@Module({
  imports: [],
  controllers: [AppController, CommodityController],
  providers: [AppService],
})
export class AppModule {}

完成上述的控制器注入后,我们启动程序时就会把对应的控制器实例创建出来,从而就可以访问到对应的接口。

你可能感兴趣的:(NestJS学习笔记,学习,NestJS,node.js)