当前位置: 首页 > 知识库问答 >
问题:

如何使用Spring管理REST API版本控制?

从渊
2023-03-14

我一直在搜索如何使用Spring3.2.x管理REST API版本,但没有找到任何易于维护的内容。我先解释一下我遇到的问题,然后再给出一个解决方案...但我不知道我是不是在重新发明轮子。

以1.0版本的API为例,到1.8版本,在1.0版本中引入了一个处理程序,并在1.7版本中进行了修改,我希望以以下方式处理这个问题。假设代码在一个控制器中,并且有一些代码能够从头中提取版本。(以下为Spring无效)

@RequestMapping(...)
@VersionRange(1.0,1.6)
@ResponseBody
public Object method1() {
   // so something
   return object;
}

@RequestMapping(...) //same Request mapping annotation
@VersionRange(1.7)
@ResponseBody
public Object method2() {
   // so something
   return object;
}

这在spring中是不可能的,因为这两个方法具有相同的requestmapping注释,并且spring无法加载。其思想是versionrange注释可以定义打开或关闭的版本范围。第一种方法从1.0到1.6版本有效,而第二种方法则适用于1.7以后的版本(包括最新的1.8版本)。我知道,如果有人决定通过99.99版本,这种方法就会中断,但这是我可以接受的。

现在,如果不对spring的工作方式进行认真的重做,就不可能实现上述操作,所以我正在考虑修补处理程序与请求匹配的方式,特别是编写自己的ProduceRequestCondition,并在其中设置版本范围。例如:

@RequestMapping(..., produces = "application/vnd.company.app-[1.0-1.6]+json)
@ResponseBody
public Object method1() {
   // so something
   return object;
}

@RequestMapping(..., produces = "application/vnd.company.app-[1.7-]+json)
@ResponseBody
public Object method2() {
   // so something
   return object;
}

这样,我就可以在注释的produces部分中定义关闭或打开的版本范围。我现在正在研究这个解决方案,问题是我仍然必须替换一些核心的Spring MVC类(RequestMappingInfoHandlerMappingRequestMappingHandlerMappingRequestMappingInfo),这是我不喜欢的,因为每当我决定升级到一个新版本的Spring时,这意味着额外的工作。

如果你有任何想法,我将不胜感激...特别是,任何以一种更简单、更易于维护的方式来实现这一点的建议。

再加一笔赏金。为了得到赏金,请回答上面的问题,不要暗示在控制器本身有这个逻辑。Spring已经有很多逻辑来选择要调用哪个控制器方法,我想借鉴它。

我在GitHub:https://github.com/augusto/restversioning中分享了原始POC(有一些改进)

共有1个答案

岳玉书
2023-03-14

不管是否可以通过进行向后兼容的更改来避免版本控制(当您受到一些公司指导方针的约束,或者您的API客户机是以错误的方式实现的,即使不这样做,也会发生故障),抽象的需求是一个有趣的需求:

我如何做一个自定义请求映射,从请求中任意计算头值,而不在方法体中进行计算?

如本文SO answer所述,您实际上可以使用相同的@requestmapping并使用不同的注释来区分运行时发生的实际路由。为此,您必须:

  1. 创建新批注versionrange
  2. 实现RequestCondition 。由于您将使用类似最佳匹配算法的方法,因此必须检查用其他versionrange值注释的方法是否为当前请求提供了更好的匹配。
  3. 基于注释和请求条件实现VersionRangeRequestMappingHandlerMapping(如如何实现@RequestMapping自定义属性的文章所述)。
  4. 配置spring以在使用默认的RequestMappingHandlerMapping之前计算您的VersionRangeRequestMappingHandlerMapping(例如,将其顺序设置为0)。

这不需要对Spring组件进行任何简单的替换,而是使用Spring配置和扩展机制,因此即使更新了Spring版本(只要新版本支持这些机制),它也应该可以工作。

 类似资料:
  • 问题内容: 我一直在搜索如何使用Spring 3.2.x管理REST API版本,但没有找到易于维护的东西。我将首先解释我所遇到的问题,然后是一个解决方案……但我确实想知道是否在这里重新发明轮子。 我想基于Accept标头管理版本,例如,如果请求具有Accept标头application/vnd.company.app-1.1+json,我希望spring MVC将其转发到处理此版本的方法。而且由

  • 如何使用SpringBoot和SpringSecurity将基本授权(登录密码)与其他服务(google、github、facebook)的授权结合起来?有很多信息,我不知道如何正确解决这个问题。我将非常感谢教程或链接到材料。

  • 1 分支管理 常用远程分支: master dev prd feature- hotfix- release- tag管理: 凡是部署版本给客户验证的,均应该打上tag以进行标识。 release管理: release分支,name字段为相应客户的名字。例如release-zhangjiakou 2 版本号规范 版本规范参考文档 <major>.<minor>.<patch>-<stage>.<

  • Unix was not designed to stop you from doing stupid things, because that would also stop you from doing clever things. — Doug Gwyn 你曾经遇到过误删除了某些文件而又希望恢复的情形吧? 本书中提及的最重要的技巧就是将 Puppet 的 配置清单(manifests)纳入像

  • 我正在使用jhipster,我想在我的WebApp中集成spring批处理管理控制台。(例如http://localhost:8080/batch-console) 我尝试在我的jhipster webapp中集成以下响应,有没有一种方法可以正确地集成spring-batch-admin和spring-boot?但我得到以下错误(属性似乎未加载) Spring Boot版本:1.4.1.发布Jhi

  • 我试图通过AWS负载平衡器公开在kubernetes集群中运行的应用程序。我遵守了文件https://cloudyuga.guru/blog/cloud-controller-manager直到我在kubeadm中添加了云提供者=外部。conf文件。但这份文档是基于数字海洋云的,我正在从事AWS的工作,我很困惑是否需要运行任何部署。yaml文件以使处于挂起状态的吊舱运行,如果是,请提供链接,我现在