48

我首先在 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 的版本控制时使用最佳实践

4

3 回答 3

18

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

插入/v2/URL 会破坏之前的所有现有链接。

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

Accept:将其放入所需标题的 mime 类型中。就像是Accept: application/myapp.2.0.1+json

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

于 2013-02-14T18:28:31.693 回答
13

此博客文章有一个示例,说明某些人认为正确的方法,即在 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"})
于 2014-08-13T15:37:34.053 回答
2

我只是想知道为什么没有一个名为 ProductService 的子类

@Path(/v2/ProductService)
ProductServiceV2 extends ProductService {


}


@Path(/v1/ProductService)
 class ProductService{


}

并且只覆盖 v2 中更改的任何内容。所有未更改的内容都将与 v1/ProductService 中的相同。

这肯定会导致更多的类,但这是一种更简单的编码方式,只针对新版本 api 中发生的任何变化并在不复制代码的情况下恢复到旧版本。

于 2015-04-06T20:56:08.770 回答