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

实践中的REST web服务版本控制

梁丘权
2023-03-14
@RequestMapping(method = RequestMethod.GET, produces = "application/vnd.example-v1+json")

版本2:

@RequestMapping(method = RequestMethod.GET, produces = "application/vnd.example-v2+json")

还是这样做错了?或者更常见的是创建不同的包来保存不同版本的控制器?还是有其他办法?

共有1个答案

西门伟
2023-03-14

这里的问题不是版本信息所在的位置(URI vs header),而是如何为不同版本组织代码。

我怀疑有一个单一的标准方法。这只是取决于版本有多大的不同。

简单的格式更改。例如,假设唯一的区别是从V1中的XML转移到V2中的JSON。在这种情况下,您可以使用完全相同的代码,但只需将应用程序配置为全局输出JSON即可。不需要不同的封装或控制器。(例如,您可以使用JAXB注释来驱动XML和Jackson生成的JSON输出。)

主要架构更改。如果您的架构更改是深入和广泛的,您可能需要的不仅仅是单独的控制器。您甚至可能需要一个不同的域模型(实体/服务)。在这种情况下,为控制器提供一组并行的包,一直到实体、repos甚至数据库表,可能是很有意义的。

方法1.将这些思想应用到@requestmapping示例中,您可以按照上面所说的去做,但是如果版本之间的响应完全相同,那么它们应该只委托给一个共享方法:

@RequestMapping(
    value = "/orders/{id}",
    method = RequestMethod.GET,
    produces = "application/vnd.example-v1")
@ResponseBody
public Order getOrderV1(@PathVariable("id") Long id) {
    return getOrder(id);
}

@RequestMapping(
    value = "/orders/{id}",
    method = RequestMethod.GET,
    produces = "application/vnd.example-v2")
@ResponseBody
public Order getOrderV2(@PathVariable("id") Long id) {
    return getOrder(id);
}

private Order getOrder(Long id) {
    return orderRepo.findOne(id);
}

像这样的东西就行了。如果不同版本的顺序不同,那么您可以在方法中实现这些差异。

// The baseline
public abstract class BaseOrderController {

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    public Order getOrder(@PathVariable("id") Long id) { ... }
}    

// V1 controller
@RequestMapping(value = "/orders", produces = "application/vnd.example-v1")
public class OrderControllerV1 extends BaseOrderController {

    ... no difference from baseline, so nothing to implement ...
}

// V2 controller
@RequestMapping(value = "/orders", produces = "application/vnd.example-v2")
public class OrderControllerV2 extends BaseOrderController {

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)
    @ResponseBody
    @Override
    public Order getOrder(@PathVariable("id") Long id) {
        return orderRepoV2.findOne(id);
    }
}
 类似资料:
  • 提交对映改动 一次提交要包括一个相关改动。例如,对于两个错误的修复应该进行两次不同的提交。精简的提交可以让其他的开发团队人员更简单地明白其改动的用义。如果其中一次提交的改动出现了问题,也可以方便地回滚到改动之前的状态。借助暂存功能来标记相关的改动文件,Git 可以为你打造出非常精准的提交。 频繁地提交改动 经常性地提交改动可以确保不会出现特别庞大的提交,同时也可以比较精准地对应到所需要的改动上。此

  • 我对Kubernetes还很陌生,只是从一个示例项目开始学习。我目前正在运行一个.NET微服务,它需要一个MongoDB作为数据库。微服务被打包到Docker映像中,我创建了一个单独的Helm图表来正确部署我的微服务和所需的MongoDB。 是这样做的吗?还是我错过了什么?所有给我指明正确方向的线索都非常欢迎!

  • 需要修改Spring Boot微服务的现有契约(请求/响应有效负载),这实际上是破坏性的更改(不向后兼容)。而且在一段时间内支持合同的两个版本--直到所有客户都升级到更新的版本--是至关重要的。 为了实现这一点,已经决定使用URL版本控制策略(如/v1/{resource}和/v2/{resource})。 现在,问题是在代码中实现这一点的最佳方式是什么?以下是两个建议的解决方案 > 扩展版本一(

  • 问题内容: 我进入了基于docker的微服务架构,我有3个微服务,它们共同创建了一个产品,例如“ CRM系统”。 现在,我希望我的客户能够随时升级他的产品。我的微服务有3个不同版本,客户应该看哪个?我猜产品版本应该独立于微服务,因为复制一个微服务版本会使我陷入麻烦,而不是根本没有版本。 那么,有什么模式,想法可以应对这种情况吗? 我唯一想到的就是拥有另一个存储库,只要其中一个微服务产生生产就绪的软

  • 本文向大家介绍Springcloud实现服务多版本控制的示例代码,包括了Springcloud实现服务多版本控制的示例代码的使用技巧和注意事项,需要的朋友参考一下 需求 小程序新版本上线需要审核,如果有接口新版本返回内容发生了变化,后端直接上线会导致旧版本报错,不上线审核又通不过。 之前是通过写新接口来兼容,但是这样会有很多兼容代码或者冗余代码,开发也不容易能想到这一点,经常直接修改了旧接口,于是

  • 眼下最流行的”版本管理系统”,非 Git 莫属! 关于是否使用 SVN? 个人的建议是如果团队有权限管理、代码安全控制等考虑的话,那么考虑 SVN,否则建议使用 Git/Mercurial, 关于 Mercurial 还是 Git,因为 GitHub 这个大社区的缘故,因此如果是程序员个人搞开源的话,还是建议优先 Git,如果 Git、Mercurial 您都想试试,那么这里打个广告:强烈建议您试