一口气说出 4 种 API 版本控制方案!

Cursor Rules实战指南:用.mdc文件实现AI编码规则自动化 在AI编程协作中,'提示词粘贴'是低效且不可维护的临时方案;真正的工程化解法是将团队约定转化为可版本控制、可精准匹配、可上下文注入的静态规则文件。Cursor Rules 通过 .mdc 格式实现规则的声明式定义,依托 alwaysApply、globs 和 Apply Intelligently 三重匹配机制,在模型推理前自动注入高优先级上下文,显著提升生成代码的一致性与可合并性。其核心价值在于将模糊的‘提示工程’升级为确定性的‘契约驱动开发’,适用于 FastAPI、Pydantic、SQLAlchem 阅读详情

点击上方“芋道源码”,选择“设为星标”

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33 更新文章,每天掉亿点点头发...

源码精品专栏

 

34dba010c2dc594753df0f8c3407d463.png


在实际项目开发中我们经常需要对接口进行版本管理。那今天我们就来聊聊为什么需要版本控制,以及如何对REST API进行版本控制。我们将讨论4种版本控制的方法,并比较不同的方法。

通过此文您将学到

  • 为什么我们需要对RESTful API 进行版本控制?

  • 可用的版本控制有哪些?

  • 如何实现基于 Restful 的版本控制?

为什么我们需要对RESTful API进行版本化

最好的版本控制方法是不进行版本控制。只要不需要版本控制,就不要版本控制。

“

“

构建向后兼容的服务,以便尽可能避免版本控制!

”

然而,在许多情况下我们都需要进行版本控制,然我们看看下面具体的例子:

最初,你有个这个版本的Student服务,返回数据如下:

{
  "name": "Bob Charlie"
}

后来,您希望将学生的名字拆分,因此创建了这个版本的服务。

{
  "name": {
    "firstName": "Bob",
    "lastName": "Charlie"
  }
}

您可以从同一个服务支持这两个请求,但是随着每个版本的需求多样化,它会变得越来越复杂。

在这种情况下,版本控制就成必不可少,强制性的了。

接下来让我们创建一个简单的SpringBoot的maven项目,并理解对 RESTful 服务进行版本控制的4种不同方法。

<dependencies>
 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter</artifactId>
 </dependency>

 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
 </dependency>

 <dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
 </dependency>

 <dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
 </dependency>
</dependencies>

几个用于实现版本控制的Bean

第一个版本的 Bean

@Data
@AllArgsConstructor
public class StudentV1 {
    private String name;
}

第二个版本的 Bean

@Data
public class StudentV2 {
    private Name name;
}

StudentV2使用的Name实体

@Data
@AllArgsConstructor
public class Name {
    private String firstName;
    private String lastName;
}
“

推荐下自己做的 Spring Boot 的实战项目:

https://github.com/YunaiV/ruoyi-vue-pro

Restful 版本控制的方法

我们希望创建两个版本的服务,一个返回 StudentV1,另一个返回 StudentV2。

让我们来看看创建相同服务版本的4种不同方法。

通过 URI 进行版本控制

@RestController
public class StudentUriController {

    @GetMapping("v1/student")
    public StudentV1 studentV1() {
        return new StudentV1("javadaily");
    }

    @GetMapping("v2/student")
    public StudentV2 studentV2() {
        return new StudentV2(new Name("javadaily", "JAVA日知录"));
    }

}

请求:http://localhost:8080/v1/student

响应:{"name":"javadaily"}

请求:http://localhost:8080/v2/student

响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}

通过请求参数进行版本控制

版本控制的第二种方法是使用请求参数来区分版本。请求示例如下所示:

  • http://localhost:8080/student/param?version=1

  • http://localhost:8080/student/param?version=2

实现方式如下:

@RestController
public class StudentParmController {

    @GetMapping(value="/student/param",params = "version=1")
    public StudentV1 studentV1() {
        return new StudentV1("javadaily");
    }

    @GetMapping(value="/student/param",params = "version=2")
    public StudentV2 studentV2() {
        return new StudentV2(new Name("javadaily", "JAVA日知录"));
    }
}

请求:http://localhost:8080/student/param?version=1

响应:{"name":"javadaily"}

请求:http://localhost:8080/student/param?version=2

响应:{"name":{"firstName":"javadaily","lastName":"JAVA日知录"}}

通过自定义Header进行版本控制

版本控制的第三种方法是使用请求头来区分版本,请求示例如下:

  • http://localhost:8080/student/header

    • headers=[X-API-VERSION=1]

  • http://localhost:8080/student/header

    • headers=[X-API-VERSION=2]

实现方式如下所示:

@RestControllerpublic class StudentHeaderController {    @GetMapping(value="/student/header",headers = "X-API-VERSION=1")    public StudentV1 studentV1() {        return new StudentV1("javadaily");    }    @GetMapping(value="/student/header",headers = "X-API-VERSION=2")    public StudentV2 studentV2() {        return new StudentV2(new Name("javadaily", "JAVA日知录"));    }}

下图展示了我们如何使用Postman执行带有请求头的Get请求方法。

请求:http://localhost:8080/student/headerheader:X-API-VERSION = 1

3fc86ac90ae7ddccf58ff255685caf40.png

请求:http://localhost:8080/student/headerheader:X-API-VERSION = 2

435f640f7b61ae7df7e29876146781b8.png

通过媒体类型进行版本控制

最后一种版本控制方法是在请求中使用Accept Header,请求示例如下:

  • http://localhost:8080/student/produce

    • headers=[Accept=application/api-v1+json]

  • http://localhost:8080/student/produce

    • headers=[Accept=application/api-v2+json]

实现方式如下:

@RestController
public class StudentProduceController {

    @GetMapping(value="/student/produce",produces = "application/api-v1+json")
    public StudentV1 studentV1() {
        return new StudentV1("javadaily");
    }

    @GetMapping(value="/student/produce",produces = "application/api-v2+json")
    public StudentV2 studentV2() {
        return new StudentV2(new Name("javadaily", "JAVA日知录"));
    }
}

下图展示了我们如何使用Postman执行带有请求Accept的Get方法。

请求:http://localhost:8080/student/produceheader:Accept = application/api-v1+json

d8fe20baf0316072523407c742cddb46.png

请求:http://localhost:8080/student/produceheader:Accept = application/api-v2+json

d4c4549c2413a26c54a256675d0941e9.png
“

推荐下自己做的 Spring Cloud 的实战项目:

https://github.com/YunaiV/onemall

影响版本选择的因素

以下因素影响版本控制的选择

  • URI 污染 - URL版本和请求参数版本控制会污染URI空间。

  • 滥用请求头 - Accept 请求头并不是为版本控制而设计的。

  • 缓存 - 如果你使用基于头的版本控制,我们不能仅仅基于URL缓存,你需要考虑特定的请求头。

  • 是否能在浏览器直接执行 ? - 如果您有非技术消费者,那么基于URL的版本将更容易使用,因为它们可以直接在浏览器上执行。

  • API文档 - 如何让文档生成理解两个不同的url是同一服务的版本?

“

“

事实上,并没有完美的版本控制解决方案,你需要根据项目实际情况进行选择。

”

下面列表展示了主要API提供商使用的不同版本控制方法:

  • 媒体类型的版本控制

    • Github

  • 自定义Header

    • Microsoft

  • URI路径

    • Twitter,百度,知乎

  • 请求参数控制

    • Amazon

好了,今天的文章就到这里了,希望能对你有所帮助。



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

7851b2b1bdcd57dbd466e6d556478d7a.png

已在知识星球更新源码解析如下:

c13f4e13fac30963a8727c7d5365ac87.png

bac09f40dbbc40035167bf0ca8706f27.png

0419d1b888238a48289c04f6a45a5030.png

2c242c69d945fd5eaa12bb6a89f2645f.png

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。
谢谢支持哟 (*^__^*)
AI驱动数据治理:从规则治理到智能决策的架构演进与实践 数据治理是企业数字化转型的基石,其核心目标是确保数据的质量、安全与一致性,从而为业务决策提供可靠支撑。传统数据治理主要依赖人工规则与流程,存在响应滞后、覆盖有限等挑战。随着机器学习与人工智能技术的发展,数据治理正从“规则驱动”向“智能驱动”演进。通过引入时间序列预测、异常检测、自然语言处理等技术,AI能够自动学习数据模式、智能识别异常、自动化资产编目,实现从事后补救到事前预警的转变。这种智能化的数据治理体系,能够将高质量数据直接转化为业务洞察,支撑精准营销、风险控制等应用场景,最终推动数据治理从成本中心向赋 阅读详情

相关推荐

中移物联ML307C模组OPENCPU笔记2

本文介绍了如何编译和运行一个DEMO程序,以官方SDK为例。

weixin_43700831的博客 1887

spring boot 接口版本控制

对于应用上线后的接口变动,前后端代码更新无法做到同时更新,容易造成报错,影响用户体验。需做好接口版本控制,在前端代码更迭时期保留旧版本接口的服务提供。

localhost 2031

Aloudata Agent :基于 NoETL 明细语义层的分析决策智能体

这是包括我们在内的一些厂商探索的一个新方向,这种方式先由大模型将自然语言转化为对指标语义层的查询请求(MQL,Metrics Query Language),再由指标平台将指标和维度的查询与计算逻辑转化为准确的 SQL 查询语句。用户查询经大模型语义解析后,将其转换为指标、维度及筛选条件的组合表达,并生成面向指标平台的 MQL,Aloudata CAN 指标平台的语义引擎将 MQL 转换为准确和可执行的查询 SQL,语义引擎内置函数体系与 SQL 解析器,确保语义转换的 100% 准确性。

Aloudata的博客 1664

很后悔,才发现这个API管理神器

当然,Apikit 还有一个特别强悍的地方,除了API管理、自动化测试服务以外,它是全球第一个API全生命周期管理的SaaS平台,还提供了包括API网关、API监控、API自动生成等服务。多个API工具的数据难以打通,比如API文档管理用Swagger、Word或者Wiki,测试用Postman,Mock自己写脚本,压力测试用Jmeter或Loadrunner,甚至一个项目内部可以同时存在多个API管理工具,多个工具之间数据无法真正打通,无法高效地维护API信息和团队协作。并在2017年正式发布了。

kungfuboy17的博客 1767

点云直线检测-3DLineDetection复现

点云直线分割-Fast 3D line detection

阁楼 8156

Shopee商品详情页反爬实战:手把手逆向x-sap-Ri和x-sap-Sec参数(附完整调试过程)

本文详细解析了Shopee商品详情页反爬机制中的x-sap-Ri和x-sap-Sec参数逆向过程。通过JS逆向技术,从环境数据采集到多层哈希运算,完整拆解了这两个关键参数的生成逻辑,并提供了实战技巧和Node.js实现方案,帮助开发者应对Shopee的动态加密挑战。

weixin_33701251的博客 1598

spring接口版本控制方案及RequestMappingHandlerMapping接口介绍

RequestMappingHandlerMapping支持多种请求映射的方式,如基于URL路径的请求映射、基于请求方法的请求映射、基于请求头的请求映射等。通过灵活的配置和扩展,可以实现请求的路由、请求的参数解析和数据绑定,以及接口版本控制等功能。RequestMappingHandlerMapping可以处理多种类型的处理器,例如带有@Controller或@RestController注解的类,实现了Controller接口的类,以及其他自定义的处理器类型。在Spring MVC中,可以通过自定义。

码到三十五 1202

跨应用服务器的自定义 IDoc 传输实战:以 CATSDB 工时为例,打通两套 SAP 系统的数据通道

本文介绍了在企业多SAP系统环境下,使用SAP ALE/IDoc技术实现工时数据跨系统传输的解决方案。文章从技术选型、系统架构到具体配置步骤进行了详细说明,重点阐述了IDoc/ALE在异步传输、全链路追踪和数据重放方面的优势。 文章详细讲解了端到端实施流程,包括Logical System配置、RFC Destination创建、Message Type定义、Segment和Basic Type设计等关键步骤。同时提供了出站封装的ABAP代码示例,强调调用MASTER_IDOC_DISTRIBUTE函数后执

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 174

API接口版本控制的实现方式

软件系统在整个生命周期当中会根据需求的不断变化进行不断的迭代更新,有可能接口的参数也会发生变化,如果在原有的参数上直接修改,可能会影响到现有项目的正常运行,这时我们就需要设置不同的版本,这样即使参数发生变化,由于老版本没有变化,因此不会影响上线系统的运行。 ...

光滑的秃头 2019

点云数据处理:体素滤波算法

体素滤波是一种简单而有效的点云数据处理方法,可用于去除离群点和平滑点云表面。体素滤波是一种常用的点云数据处理算法,用于去除离群点并平滑点云表面。在本文中,我们将介绍CloudCompare和PCL(Point Cloud Library)中的体素滤波算法,并提供相应的源代码示例。PCL是一个专门用于点云处理的开源库,提供了一系列高效的点云处理算法和工具。然后,我们创建了一个。方法执行体素滤波,并将滤波后的点云保存为"filtered_cloud.ply"文件。方法来执行体素滤波,指定体素大小为0.01。

ZyqfCss的博客 390

Android 13.0 app进程保活白名单功能实现

在13.0的系统rom产品开发中,在某些重要的app即使进入后台,产品需求要求也不想被系统杀掉进程,需要app长时间保活,就是app进程保活白名单功能的实现, 所以需要在系统杀进程的时候不杀掉白名单的进程,接下来就看怎么样来实现这些功能

安卓兼职framework和app工程师的博客 3143

Java实战:实现API版本化管理方案

本文将详细介绍如何实现API版本化管理方案。我们将探讨API版本化管理的概念,以及如何使用Spring Boot和Spring MVC来实现API版本控制

oandy0的博客 2441

补丁1.0:使用Eviews做ADF检验

补丁1.0:使用Eviews做ADF检验

Jet4505的博客 1961

程序员翻车时的 30 种常见反应!

码个蛋(codeegg) 第 1056 次推文作者:Jake Rocheleau链接:https://mp.weixin.qq.com/s/pKS6Pxzs4QmFxilNwG9iXA前...

陈宇明 474

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

程序员翻车时的 30 种常见反应!第21个深有感触...

软件开发工作充满了挑战性。人无完人,对于程序员来说,写出有 bug 的代码是在所难免的。有些人很淡定,也有一些人会感到生气、沮丧、不安或气馁。在修复 bug 的过程中我们都经历了什么?这...

emprere的博客 432

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

2个网页跳来跳去_程序员翻车时的 30 种常见反应!第21个深有感触...

软件开发工作充满了挑战性。人无完人,对于程序员来说,写出有 bug 的代码是在所难免的。有些人很淡定,也有一些人会感到生气、沮丧、不安或气馁。在修复 bug 的过程中我们都经历了什么?这个值得我们一探究竟。本文列出了程序员在修复 bug 时可能会说的一些话或者想法。我敢说很多程序员都曾经历过编程的艰辛,但在事后都会一笑而过。1. “我不知道该把它删掉还是该重写”看着旧代码,你总有一种想要重写它们的...

weixin_39552304的博客 297

程序员翻车时的 30 种常见反应!第 21 个深有感触...

code小生一个专注大前端领域的技术平台 公众号回复Android加入安卓技术群 作者 | Jake Rocheleau编辑 | 程序员遇见github软件开发工作充满了挑战性。人无...

weixin_38754349的博客 206

python创建数据库为什么只能有4个值、多一个就报错_99%的程序员在报错时的 30 种常见反应,太让人捧腹大笑了...

软件开发工作充满了挑战性。人无完人,对于程序员来说,写出有 bug 的代码是在所难免的。有些人很淡定,也有一些人会感到生气、沮丧、不安或气馁。在修复 bug 的过程中我们都经历了什么?这个值得我们一探究竟。本文列出了程序员在修复 bug 时可能会说的一些话或者想法。我敢说很多程序员都曾经历过编程的艰辛,但在事后都会一笑而过。1. “我不知道该把它删掉还是该重写”看着旧代码,你总有一种想要重写它们的...

weixin_39757212的博客 188

就在刚刚,某程序员翻车了...翻车现场如文。。。

点击上方[全栈开发者社区]→右上角[...]→[设为星标⭐]软件开发工作充满了挑战性。人无完人,对于程序员来说,写出有 bug 的代码是在所难免的。有些人很淡定,也有一些人会感到生气、沮...

全栈开发者社区 412

为什么devc调试时循环一下就过去了_程序员在报错时的30种常见反应

软件开发工作充满了挑战性。人无完人,对于程序员来说,写出有 bug 的代码是在所难免的。有些人很淡定,也有一些人会感到生气、沮丧、不安或气馁。在修复 bug 的过程中我们都经历了什么?这个值得我们一探究竟。本文列出了程序员在修复 bug 时可能会说的一些话或者想法。我敢说很多程序员都曾经历过编程的艰辛,但在事后都会一笑而过。1. “我不知道该把它删掉还是该重写”看着旧代码,你总有一种想要重写它们的...

weixin_39559523的博客 332

AI 应用工程师学习路线图:6 个月从 CRUD 到能独立交付

AI编程不仅是与AI对话,而是需要掌握完整开发流程,从需求描述到交付上线。六个阶段包括:入门(先做出小工具)、工具掌握(选择1-2个主流AI编程工具)、核心技能(需求分析、提示词工程等)、项目实战(分难度递进)、进阶选修(按目标选择深入学习)、持续学习(保持技术更新)。作者强调学习应循序渐进,不同目标对应不同学习路径(2周-6个月),关键是要快速获得"能用AI做出东西"的成就感,再逐步深入。整体系列的核心是教会读者如何将AI编程工具与工程化思维结合,实现从原型到产品的完整交付能力。

liwan09的博客 398

Python开发实习全攻略:从小白到转正的18周实战之旅

Python以其简洁的语法、丰富的生态和广泛的应用场景(Web开发、数据分析、人工智能、自动化运维等),成为众多企业招聘实习生的热门技术栈。本文将围绕“Python开发工程师”实习岗位,系统性地解答这三个核心问题,帮助你理清思路,更有准备地开启第一段职业旅程。无论你是大二/大三正在寻找第一份实习,还是已经拿到Offer准备入职,这篇文章都能为你提供有价值的参考。这是你的“基础版”简历,需要清晰展示你的技术栈、项目经历和教育背景。理解这两者的区别,能帮助你更好地适应实习,并最大化实习价值。

热爱技术与前沿创新,深耕科技领域,在科创中精进自我;探索技术乐趣,分享技术干货与成长心得,以技术为伴,热爱生活,在科创与生活中双向成长。 273

一周深度学习实战课:认知脚手架搭建与教学节奏控制

深度学习入门教学面临的核心矛盾,是知识复杂性与人类认知带宽的天然冲突。基于工作记忆容量限制(Miller定律)和神经网络可解释性需求,现代短周期AI课程必须从‘知识灌输’转向‘认知转译’——将反向传播具象为梯度流、把卷积核类比为图像滤镜、用Excel可视化损失曲面。这种以‘可操作、可观察、可修复’为准则的教学设计,本质上是面向零基础学习者的认知压缩工程,适用于高校短期选修课、企业AI通识培训及跨学科技术扫盲。本文聚焦真实课堂验证的72小时作战地图,覆盖数据加载、模型乐高化构建、梯度可视化、失败驱动评估与零配

dezhen7015的博客 458

springboot接口如何控制版本?

1、springBoot接口如何控制版本? 2、org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping的用途和使用

燕少江湖 1649
上一篇: Nginx配置反向代理,一篇搞定!
下一篇: SpringBoot+MDC实现全链路调用日志跟踪,非常实用!
公众号-芋道源码
博客等级 码龄10年 1634粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值