介绍
在开始前我们先了解一下:Nest中的controller是什么?有什么作用?
- 控制器是我们
controller.ts
文件中的Controller装饰器部分,控制器负责处理传入的请求和向客户端返回响应。 - 控制器的目的是接收应用的特定请求。路由机制控制哪个控制器接收哪些请求。通常,每个控制器有多个路由,不同的路由可以执行不同的操作。为了创建一个基本的控制器,我们使用类和
装饰器
。装饰器将类与所需的元数据相关联,并使 Nest 能够创建路由映射(将请求绑定到相应的控制器)。
所以Controller的作用几乎都是围绕着匹配路由来作用着的。上面的装饰器便是对应着该路径的的请求方法。
那路由还需要有子路径
,动态路由
,请求方法
等许多能力等实现,都将在Contreller内提供。
路由
子路径方法匹配
当启动一个nest服务时,跟着有许多的子路径,与express服务启动类似的,我们对于子路径的规则匹配都是直接定义路径即可实现。
类似于上图,只需要在对应的装饰器内传入对应路径的参数,我们便可以再这个基础上实现子路径该请求方法的开放能力。那他们的区别在哪里呢?
当我们子路径放在@Controller内部,子路径匹配的是所有方法
而当我们将路径放在对应的方法内就必须要 路径 + 方法 一起对应起来才行
请求细节Request
在请求响应中,处理程序有时需要访问客户端的请求细节。Nest底层平台为Express
所构建。所有我们可以在处理函数的签名中使用 @Req()
装饰器来获取express中的req对象,指示 Nest 将请求对象注入处理程序。
import { Controller, Get, Post, Req } from '@nestjs/common';
import { AppService } from './app.service';
import { Request } from 'express';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('info')
getHello(@Req() request: Request): string {
console.log(request);
return this.appService.getHello();
}
}
使用方法也是比较简单,只需你你需要什么便触发对应逻辑便可以了
路由通配符
@Get('a*b')
getHello(): string {
return this.appService.getHello();
}
路由路径 'ab*cd'
将匹配 abcd
、ab_cd
、abecd
等。字符 ?
、+
、 *
以及 ()
是它们的正则表达式对应项的子集。连字符(-
) 和点(.
)按字符串路径逐字解析。
状态码
http默认情况下成功响应的状态码总是默认为 200,除了 POST 请求(默认响应状态码为 201),nest可以通过在处理函数外添加 @HttpCode(...)
装饰器来更改此行为。HttpCode
需要从 @nestjs/common
包导入。
@Get()
@HttpCode(666)
getHello() {
return this.appService.getHello();
}
响应头
要指定自定义响应头,可以使用 @header()
装饰器或类库特有的响应对象,(并直接调用 res.header()
)。具体方法与状态吗类似
@Get()
@Header('Cache-Control', 'none')
getHello() {
return this.appService.getHello();
}
重定向
要将响应重定向到特定的 URL
,可以使用 @Redirect()
装饰器或特定于库的响应对象(并直接调用 res.redirect()
)。
@Redirect()
装饰器有两个可选参数,url
和 statusCode
。 如果省略,则 statusCode
默认为 302
。
@Get()
@Redirect('https://www.baidu.com/', 302)
如果你想动态地决定 HTTP 状态代码或重定向 URL。通过从路由处理方法返回一个如下格式的对象:
{
"url": string,
"statusCode": number
}
这样根据判断条件将会覆盖默认重定向
路由参数
当我们需要接受动态数据作为请求的一部分时(例如,使用GET/1
来获取路径 id 为 1
),带有静态路径的路由将无法工作。我们可以在路由路径中添加路由参数标记以捕获请求 URL 中该位置的动态值。
Param
需要从 @nestjs/common
包导入。
import { Controller, Get, Param } from '@nestjs/common';
import { AppService } from './app.service';
interface Params {
id: string;
}
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get('v1/:id')
getHello(@Param() params: Params) {
console.log(params.id);
return this.appService.getHello(params.id);
}
@Get()
getHello2(): string {
return this.appService.getHello2();
}
}
子域路由
@Controller
装饰器可以接受一个 host
选项,以要求传入请求的 HTTP
主机匹配某个特定值。
与一个路由路径 path
类似,该 hosts
选项可以使用参数标识(token)来捕获主机名中该位置的动态值。下面的 @Controller()
装饰器示例中的主机参数标识(host parameter token)演示了此用法。可以使用 @HostParam()
装饰器访问以这种方式声明的主机参数,该装饰器应添加到方法签名中。
@Controller({ host: 'admin.example.com' })
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
index(): string {
return 'Admin page';
}
}
注: 要在本地实验 NestJS 的子域路由,由于无法直接在本地使用实际的 DNS 进行子域解析,你可以通过配置本地的 /etc/hosts
文件来模拟不同的子域。通过 Express 服务器来处理请求,并且配置本地 DNS 将子域指向本地服务器。
以上的一些基础知识对于初识nest的Controller已经够了,还有一些异步,负载,错误处理什么的,当作进阶学习吧!