Nest 实现接口多版本管理

在软件开发中,随着应用的迭代更新,经常需要引入新的接口版本同时保留旧版本以保证向后兼容。

本教程将通过 NestJS 框架演示如何实现接口的多版本管理。

创建和运行项目

首先,我们需要创建一个新的 NestJS 项目,并启动服务:

bash 复制代码
nest new version-test -p pnpm
cd version-test
nest g resource TestVersion --no-spec
pnpm start:dev

启用接口版本控制

main.ts 文件中,引入版本控制功能,并设置版本信息通过 HTTP 头部传递:

typescript 复制代码
import { VersioningType } from '@nestjs/common';
import { AppModule } from './app.module';
import { NestFactory } from '@nestjs/core';

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

  app.enableVersioning({
    type: VersioningType.HEADER,
    header: 'version', // 指定传递版本信息的 HTTP 头部字段名为 'version'
  });

  await app.listen(3000);
}

bootstrap();

配置版本控制

在控制器中,我们可以通过 @Version 装饰器指定接口版本。

例如,将默认接口设置为版本 1,并为新版本创建专门的接口:

typescript 复制代码
import { Controller, Get, Version } from '@nestjs/common';
import { TestVersionService } from './test-version.service';

@Controller('test-version')
export class TestVersionController {
  constructor(private readonly testVersionService: TestVersionService) {}

  @Get()
  @Version('1')
  findAllV1() {
    return this.testVersionService.findAll();
  }

  @Get()
  @Version('2')
  findAllV2() {
    return this.testVersionService.findAll() + '版本2';
  }
}


带上不同的请求头,获得的结果不一样。

版本中立的接口

如果希望某些接口无论什么版本号如何都能访问,可以使用 VERSION_NEUTRAL 常量:

typescript 复制代码
import { VERSION_NEUTRAL, Controller, Get } from '@nestjs/common';

@Controller({
  path: 'test-version',
  version: VERSION_NEUTRAL
})
export class NeutralAaaController {
  // 接口实现
}

其他版本控制方式

NestJS 还支持通过媒体类型(Media Type)或 URI 路径来控制版本:

Media Type

版本信息通过 Accept 头部传递:

typescript 复制代码
app.enableVersioning({
    type: VersioningType.MEDIA_TYPE,
    key: 'vvv='
})

如果客户端希望请求版本 1 的 API,它需要在 HTTP 请求的 Accept 头部中加入如下内容:

bash 复制代码
Accept: application/json;vvv=1

URI 版本控制

版本信息直接在 URL 路径中指定:

typescript 复制代码
app.enableVersioning({
  type: VersioningType.URI,
});

在这个设置下,如果客户端需要访问版本 1 的 API,URL 应该像这样:

bash 复制代码
http://localhost:3000/v1/users

对于版本 2,URL 应该是:

bash 复制代码
http://localhost:3000/v2/users

这种方式使得版本控制非常明显,客户端一看 URL 就能明白所请求的 API 版本。但可能会导致 URL 空间的膨胀。

注意这种方式不支持 VERSION_NEUTRAL,需要明确版本号:

typescript 复制代码
@Controller({
  path: 'test-version',
  version: ["2", "3"]
})

自定义版本控制逻辑

如果内置的版本控制方式不满足需求,可以实现自定义版本控制逻辑:

typescript 复制代码
import { VersioningType, NestFactory } from '@nestjs/common';
import { AppModule } from './app.module';
import { Request } from 'express';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  const extractor = (request: Request) => {
    if (request.headers['disable-custom']) {
      return '';
    }
    return request.url.includes('yun') ? '2' : '1';
  };
  app.enableVersioning({
    type: VersioningType.CUSTOM,
    extractor
  });
  await app.listen(3000);
}

bootstrap();



相关推荐
.生产的驴11 分钟前
React 集成Redux数据状态管理 数据共享 全局共享
前端·javascript·react.js·前端框架·css3·html5·safari
IT_陈寒13 分钟前
Redis性能优化的7个隐藏技巧:从慢查询到亿级QPS的实战经验分享
前端·人工智能·后端
thinktik30 分钟前
AWS EKS 计算资源自动扩缩之Karpenter[AWS 海外区]
后端·kubernetes·aws
风象南30 分钟前
告别重复编码!SpringBoot + JSON Schema 动态表单开发
后端
艾小码31 分钟前
ES6+革命:8大特性让你的JavaScript代码质量翻倍
前端·javascript
JaguarJack33 分钟前
PHP 异常处理全攻略 Try-Catch 从入门到精通完全指南
后端·php
lang2015092833 分钟前
Spring Boot Actuator应用信息Application Information全解析
spring boot·后端·elasticsearch
两个西柚呀35 分钟前
Vue组件的一些底层细节
前端·javascript·vue.js
paopaokaka_luck36 分钟前
基于SpringBoot+Vue的DIY手工社预约管理系统(Echarts图形化、腾讯地图API)
java·vue.js·人工智能·spring boot·后端·echarts
IT技术分享社区38 分钟前
前端:浏览器Content Security Policy 安全策略介绍和用法
前端·前端开发