处理 JAX-RS REST API URI 版本控制的最佳方式

2022-08-31 22:36:35

我首先在stackoverflow中进行了搜索,但我无法找到与我的问题相关的任何答案。我能找到的只是与REST uri设计相关的问题。

我的问题是在后端。假设我们有两个不同版本的 REST uri

http://api.abc.com/rest/v1/products

http://api.abc.com/rest/v2/products

在后端(服务器端代码)上遵循的最佳方法是什么,以便在基于版本的这两组API中正确路由,可管理性和重用现有类?

我已经想到了使用不同@Path注释来定义资源类的方法,例如,分别为v1和v2设置一个包,在该包的ProductsResource类中,定义

    package com.abc.api.rest.v1.products;
    @Path("/rest/v1/products")
    public class ProductsResource {...}

    package com.abc.api.rest.v2.products;
    @Path("/rest/v2/products")
    public class ProductsResource {...}

然后拥有基于版本的实现逻辑。这种方法的问题在于,当我们只从api集中更改一个特定的资源API时,我们还必须将其他类复制到v2包中。我们能避免它吗?

如何编写一个自定义注释,说@Version并具有它支持的版本的值?现在,无论是 v1 还是 v2,两个请求都将转到同一资源类。

例如,例如

    package com.abc.api.rest.products;
    @Path("/rest/{version: [0-9]+}/products")
    @Version(1,2)
    public class ProductsResource {...}

更新:

Jarrod 提出了一个 API 版本控制建议来处理标头中的版本。这也是这样做的一种方法,但是,我期待着当我们遵循基于URI的版本控制时使用最佳实践。


答案 1

将其放在URL中的问题在于URL应该按位置表示资源。API 版本不是位置,也不是资源标识符的一部分。

粘贴 URL 会破坏之前的所有现有链接。/v2/

有一种正确的方法来指定 API 版本控制:

将其放在所需标头的哑剧类型中。类似的东西Accept:Accept: application/myapp.2.0.1+json

责任链模式在这里很好,特别是如果会有大量不同的API版本,以至于必须有自己的处理程序,这样方法就不会失控。


答案 2

这篇博客文章有一个示例,说明某些人认为是正确的方法,即URI中没有版本:http://codebias.blogspot.ca/2014/03/versioning-rest-apis-with-custom-accept.html

简而言之,它利用 JAX-RS 注释将特定版本的请求与特定实现相关联,例如:@Consume

@Consumes({"application/vnd.blog.v1+xml", "application/vnd.blog.v1+json"})