【问题标题】:How to manage REST API versioning with spring data rest?如何使用 Spring Data Rest 管理 REST API 版本控制?
【发布时间】:2015-08-28 11:57:30
【问题描述】:

我在Spring Rest Data的官方网站上找不到任何关于 API 版本控制的信息

我找到了Joshua Long presentations about REST APIs with Spring

API 版本可以通过以下两种方式之一实现:

第一种方法有一些问题描述here

【问题讨论】:

    标签: rest spring-data-rest


    【解决方案1】:

    这是一个有趣的话题。 spring-data-rest 的文档没有提到版本控制的最佳实践。

    根据我对 spring-data-rest 的了解,如果不实现自定义控制器,就不可能实现媒体类型版本控制。

    当然,当前的功能允许基于 URI 的版本控制:

    • 始终在您的实体中包含一个版本 - 无论是在包名中还是在类名中 - 例如com.company.v1.MyEntitycom.company.MyEntityV1
    • 在存储库中使用@RepositoryRestResource 包含URI 中的版本

      @RepositoryRestResource(path = "/v1/shops")

    因此,当您对 API 进行重大更改时,您始终可以创建新的实体版本,并使用新的存储库在 API 上公开新版本。

    编辑: 我们在团队中讨论了这个话题,我想分享一些关于 REST API 版本控制的新有趣想法。

    我想我们都同意上面概述的想法不是一个优雅的想法。它引入了很多代码重复,当您关闭旧版本时,您必须将其从代码库中删除——这可能比您想象的要难。同时,您必须在代码库中维护两个版本。你总是想避免这种情况。

    那么有什么选择。您可以做我们在微服务世界中经常做的事情 - 将复杂性推向基础架构。在微服务基础架构中创建和运行新的运行时相当容易,因此我们可以选择运行同一服务的两个不同版本。旧版本提供旧 API 版本,新版本支持我们的新版本。 API 网关可以接管路由,例如基于 HTTP 标头(Accept 或 Content-Type)或 URI 中包含的版本信息。如果你想摆脱旧版本,你只需要关闭运行旧版本的运行时就可以了。我认为这可能是一个优雅的解决方案,可以让您的代码库保持干净。

    您的基础架构可能已经支持运行同一服务的不同版本以支持blue-green deployment scenarios。这意味着您已经拥有一些可以构建的路由功能。

    我还认为,如果您支持蓝绿部署方案(您应该这样做),您必须保持版本之间的数据库架构版本兼容(例如,您的服务的旧版本需要能够在新架构版本上运行)。如果您必须保持这种级别的兼容性,那么在大多数情况下避免 REST API 版本控制可能并不难。所以你不必经常这样做——也许只有在你做出根本性的改变时(无论如何你都不会在同一个代码库中这样做)。

    【讨论】:

    • 据此stackoverflow.com/questions/30396953/… 添加斜线到@RepositoryRestResource 将不起作用
    • 如果您“将复杂性推向基础架构”,您如何处理需要更改数据模型的情况?这不会破坏旧代码库的@Entity吗?
    【解决方案2】:

    借助 RepositoryRestResource,您可以使用投影 (org.springframework.data.rest.core.config.Projection)。

    import org.springframework.data.rest.core.config.Projection
    
    @Projection(name = "v1", types = [Customer])
    interface CustomerV1 {
    
        @Value("#{target.id}")
        String getId()
    
        String getTelephone()
    
        String getName()
    }
    
    @Projection(name = "v2", types = [Customer])
    interface CustomerV2 {
    
        String getTelephone()
    
        String getName()
    }
    

    然后,每个客户端都可以使用 queryParam ?projection=vx 调用它自己的版本

    例如:curl http://localhost:8080/customer/1?projection=v1

    【讨论】:

      猜你喜欢
      • 2013-12-10
      • 2017-03-15
      • 2012-05-31
      • 2018-09-30
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 2012-12-25
      • 2017-06-14
      相关资源
      最近更新 更多