如何在 NestJS 中使用版本控制
在开发 REST API 时,需要进行重大更改并可能影响端点的合同或行为的情况并不少见。
进行重大更改的问题是消费者会受到影响,无论他们是否需要快速更改他们的应用程序以解决我们的重大更改,或者有以前没有发生的意外行为。不管影响如何,在不支持先前版本的情况下进行重大更改是不切实际的。
这就是版本控制的用武之地。版本控制允许我们拥有同时处于活动状态的不同版本的端点。它允许开发人员制作包含重大更改的新版本,同时仍然能够支持以前的版本。这使消费者可以按照自己的时间表进行升级,总体上减少了麻烦。
NestJS 是一个用于构建 Node.js 服务器端应用程序的框架。我不会在本文中详细介绍 NestJS 是什么以及为什么要使用它,但我建议查看他们的文档!
版本控制已添加到 2021 年 7 月发布的 NestJS v8 中,因此我们将在本文的示例中使用该版本。
在 NestJS 中,支持 3 种类型的版本控制:
- URI 版本控制:版本在请求的 URI 中传递
- Header 版本控制:自定义请求标头将指定版本
- 媒体类型版本控制:接受请求标头将指定版本
对于本文的重点,我们将使用媒体类型版本控制。
设置 NestJS 应用程序
本节将引导大家使用版本控制所需的设置来设置新的 NestJS 应用程序。
首先,确保你安装了 node v10.13.0 或更高版本,以及 npm,它应该与 node 一起自动安装。
接下来,我们将安装并使用 NestJS CLI 来生成一个新的应用程序。
$ npm i -g @nestjs/cli
$ nest new nest-versioning-demo
选择自己喜欢的包管理器并等待安装依赖项。
可以使用以下命令启动应用程序:
$ npm start
并使用以下命令验证它是否已启动并运行:
$ curl localhost:3000
Hello World!
在 NestJS 应用程序中启用版本控制
为了使用版本控制,我们必须在应用程序上启用该功能。 这将为整个应用程序启用版本控制,包括所有控制器和路由。
更新你的 main.ts 文件从而包含 enableVersioning(...)
函数调用:
import { VersioningType } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.enableVersioning({
type: VersioningType.MEDIA_TYPE,
key: 'v=',
});
await app.listen(3000);
}
bootstrap();
enableVersioning
函数采用一个对象参数,该参数包括要使用的版本控制类型以及该类型所需的任何配置。
对于本文,我们将使用前面描述的媒体类型版本控制。 我们可以使用 VersioningType
枚举(从 @nestjs/common 导入)来表明这一点。 媒体类型版本控制需要一个额外的配置 key ,它应该存在于 Accept 标头中,作为我们应该用于版本的值的前缀。
对于本文,我们将使用键 v=
,我们的 Accept 标头看起来像 Accept: application/json;v=1 或 Accept: application/json;v=2
。
添加版本化路由
为我们的应用程序启用版本控制后,下一步是添加版本控制路由。
运行以下命令以生成新控制器:
$ nest g controller Hello
生成文件后,更新 src/hello/hello.controller.ts 文件以包含以下方法:
import { Controller, Get } from '@nestjs/common';
@Controller('hello')
export class HelloController {
@Get()
getHelloV1() {
return 'Hello World V1!';
}
@Get()
getHelloV2() {
return 'Hello World V2!';
}
}
如果我们现在运行应用程序并向 localhost:3000/hello
发出请求,我们将看到响应 Hello World V1! 无论我们在 Accept 标头中发送的版本如何。 这是因为我们没有告诉 NestJS 哪个函数应该用于哪个版本,所以它默认为第一个。
要指定版本,我们有两个选项:
- 为整个控制器指定一个版本
- 指定特定路线/功能的版本
我们将从向路线添加一个版本开始。 为此,我们使用 @Version 装饰器(从 @nestjs/common 导入)。 更新 src/hello/hello.controller.ts 文件以在函数中包含相应的版本:
import { Controller, Get, Version } from '@nestjs/common';
@Controller('hello')
export class HelloController {
@Version('1')
@Get()
getHelloV1() {
return 'Hello World V1!';
}
@Version('2')
@Get()
getHelloV2() {
return 'Hello World V2!';
}
}
现在我们可以向两个版本化的路由发出请求并验证返回的响应:
$ curl localhost:3000/hello -H "Accept: application/json;v=1"
Hello World V1!
$ curl localhost:3000/hello -H "Accept: application/json;v=2"
Hello World V2!
我们有一个版本化的路线!
注意
:如果请求没有版本,或者版本没有匹配的路由,应用程序将响应 404 Not Found。
添加版本化控制器
除了将版本应用于特定路由之外,我们还可以将版本应用于整个控制器以及该控制器内的所有路由。
我们将通过生成两个新控制器来做到这一点:
$ nest g controller HolaV1
$ nest g controller HolaV2
生成文件后,我们将更新两个控制器以使用相同的 hola 路由路径,并添加它们各自的版本。
src/hola-v1/hola-v1.controller.ts :
import { Controller, Get } from '@nestjs/common'; @Controller({ path: 'hola', version: '1', }) export class HolaV1Controller { @Get() getHola() { return 'Hola Mundo V1!'; } }
src/hola-v2/hola-v2.controller.ts :
import { Controller, Get } from '@nestjs/common'; @Controller({ path: 'hola', version: '2', }) export class HolaV2Controller { @Get() getHola() { return 'Hola Mundo V2!'; } }
现在我们可以向两个版本控制器发出请求并验证返回的响应:
$ curl localhost:3000/hola -H "Accept: application/json;v=1"
Hola Mundo V1!
$ curl localhost:3000/hola -H "Accept: application/json;v=2"
Hola Mundo V2!
好了,我们现在有了版本控制器!
添加版本中性路由
对于不需要版本控制的场景,NestJS 有一个“版本中性”模式,表示无论请求中的版本如何,或者请求中没有版本,都应该使用特定的函数。
注意
:对于 URI 版本控制,版本中性路由不会在 URI 中包含版本。 因此,如果在版本中性路由上发送版本,NestJS 将无法匹配 URI。
对于版本中性,我们将生成一个新控制器:
$ nest g controller Health
为了表明控制器或路由是版本中性的,我们将使用从 @nestjs/common
导入的 VERSION_NEUTRAL 符号。 我们还将向控制器添加一个 GET 路由:
import { Controller, Get, VERSION_NEUTRAL } from '@nestjs/common';
@Controller({
path: 'health',
version: VERSION_NEUTRAL,
})
export class HealthController {
@Get()
getHealth() {
return 'Healthy!';
}
}
为了验证版本中性路由,我们可以在有版本和没有版本的情况下对其进行测试:
$ curl localhost:3000/health -H "Accept: application/json;v=1"
Healthy!
$ curl localhost:3000/health
Healthy!
现在我们也有一个版本中性的路线!
总结
在本文中,我们展示了如何在 NestJS 应用程序上启用版本控制并创建版本控制的路由、控制器和版本中性的控制器。
版本控制是 API 框架中非常有用的功能,它可以响应不断变化的需求并做出重大更改,同时仍然能够支持消费者可能使用的先前版本。 NestJS 的最新版增加了将它用于我们的 Node.js REST API 的许多原因。
我希望这篇文章对大家使用 NestJS 的旅程有所帮助!
相关文章
如何在 NestJS 中使用 DTO 进行验证
发布时间:2022/04/24 浏览次数:609 分类:WEB前端
-
这里我们将讨论 NestJS 中的数据传输对象 (DTO) 以及如何使用它们来验证请求。
Nest.JS 用户注入详细介绍
发布时间:2022/04/23 浏览次数:260 分类:WEB前端
-
Nest.JS 是最流行的 Node.js 框架。 它利用 TypeScript 的全部功能使开发过程快速而简单。 在本文中,我将分享非常酷且有用的技巧“用户注入(User Injection)”,它可以大大简化我们的 Nest.JS
在 NestJS 中实现外部定义的配置设置
发布时间:2022/04/21 浏览次数:498 分类:WEB前端
-
你可能已经花了一些时间使用了很棒的 NestJS 框架,现在是时候看看如何为你的配置设置获取一些外部定义的值,比如一些键或全局变量