NestJs 中如何实现 API 版本管理功能 ❓❓❓

719 阅读4分钟

随着应用的更新和功能的迭代,API 会不断增加新的功能或做出一些破坏性更改。如果没有合适的版本控制机制,一旦客户端调用的 API 版本过时或出现不兼容的更改,就会导致客户端无法正常工作。API 版本管理可以帮助我们:

  1. 保证现有客户端的稳定性。

  2. 允许新的 API 功能发布,不破坏已有的接口。

  3. 更好地管理后端和客户端之间的兼容性。

接下来在这篇文章中我们将了解到如何在 NestJs 中实现多版本管理。

基础配置

在 NestJS 中,版本管理通过 @nestjs/common 提供的 enableVersioning() 方法来启用。你可以在应用启动时设置如何管理 API 的版本,NestJS 提供了多种控制版本的方式:路径、查询参数、请求头等。

enableVersioning 是用来启用 API 版本管理的关键方法,它接受一个配置对象。常见的配置方式如下:

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { VersioningType } from "@nestjs/common";

async function bootstrap() {
  const app = await NestFactory.create(AppModule);

  app.enableVersioning({
    type: VersioningType.URI,
    prefix: "v",
  });

  await app.listen(3000);
}
bootstrap();

在上述代码中,我们启用了版本管理,并指定了使用路径作为版本控制的方式,同时版本号将作为路径的一部分,前缀是 v。这意味着请求 URL 会像 http://localhost:3000/v1/catshttp://localhost:3000/v2/cats

通过控制器和版本实现不同的接口

接下来,我们通过创建不同版本的控制器来管理不同版本的接口。

在 NestJS 中,你可以在控制器中使用 @Controller() 装饰器的 version 属性来为每个控制器指定版本号。

import { Controller, Get, Version } from "@nestjs/common";
import { AppService } from "./app.service";

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  @Version("1")
  getHello(): string {
    return this.appService.getHello();
  }

  @Get()
  @Version("2")
  getHi(): string {
    return "this.appService.getHello()";
  }
}

最简单的方式就是这样,直接调用 version 的装饰器,指定版本号,最终结果如下图所示:

20241202113915

20241202113930

我们也可以直接在 Controller 装饰器中指定整个路由,如下所示:

import { Controller, Get, Version } from "@nestjs/common";
import { AppService } from "./app.service";

@Controller({
  path: "", // 这里指定了路由路径
  version: "1", // 这里指定了版本号
})
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get()
  getHi(): string {
    return "this.appService.getHello()";
  }
}

这个时候我们访问 v2 是访问不到的了,而访问 v1 是可以访问的:

20241202114128

20241202114141

和前面的不同,当访问 URL 时,NestJS 会根据版本号来选择正确的控制器。

版本控制的不同方式

NestJS 提供了几种方式来控制 API 的版本,你可以根据实际需求选择适合的版本控制方式。

最常见的方式是通过 URL 路径来控制 API 版本。在我们前面的例子中,已经展示了如何通过 v1, v2 等路径来区分不同版本的接口。路径版本控制简洁明了,适用于大多数场景。

app.enableVersioning({
  type: VersioningType.Query, // 使用查询参数作为版本控制方式
  defaultVersion: "1", // 默认版本为 v1
});

你还可以通过请求头中的 Accept 字段来控制版本号。使用这种方式时,客户端需要在请求中带上自定义的 Accept 头来指定版本号。

配置如下:

app.enableVersioning({
  type: VersioningType.Header, // 使用请求头版本控制
});

客户端可以在请求中添加自定义的 Accept 头来指定版本号:

version: 1 访问 v1 版本。
version: 2 访问 v2 版本。

此时,API 的版本将通过 Header 参数传递。例如:

20241202123531

20241202123547

更多更复杂的控制方式还可以使用 custom,更多用法可以参考官方文档:

20241202125338

总结

NestJS 提供了非常灵活且强大的 API 版本管理功能,支持通过路径、查询参数、请求头等多种方式来控制 API 的版本。你可以根据实际需求选择合适的版本控制方式,并通过不同的控制器实现不同版本的 API。同时,合理的版本管理策略能够确保 API 的稳定性和兼容性,避免对现有客户端造成影响。

最后再来提一下这两个开源项目,它们都是我们目前正在维护的开源项目:

如果你想参与进来开发或者想进群学习,可以添加我微信 yunmz777,后面还会有很多需求,等这个项目完成之后还会有很多新的并且很有趣的开源项目等着你。