处理JAX-RS REST API URI版本的最佳方法

我在我的search首先在stackoverflow我无法find任何答案有关我的问题。 我所能find的只是与REST uridevise有关的问题。

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

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

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

在后端(服务器端代码)上遵循的最佳方法是在基于版本的这两套api上对现有类进行正确的路由,可pipe理性和重用?

我曾经想过使用不同的@Path注释来定义资源类,例如,分别在包的ProductsResource类中分别包含v1和v2的包,define

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版本控制的build议来处理标题中的版本。 这也是一种方法,但是我期待在遵循基于URI的版本控制时使用最佳实践

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

Sticking /v2/在URL中打破了之前所有的现有链接。

有两种适当的方式来指定API版本:

  1. 把它放在你想要的Accept:标题的MIMEtypes中。 像Accept: application/myapp.2.0.1+json

  2. 把它放在一个Header不在URL中。 然后,处理资源的方法可以查看Header并确定要分派到哪个处理程序方法或对象。 类似于Version: 2.0.1

职责链模式在这里得到了很好的发挥,尤其是如果将有大量的API版本不同,必须有自己的处理程序,这样的方法不会失去控制。

这个博客文章举了一个例子,一些人认为是正确的方法,即没有在URI中的版本: http : //codebias.blogspot.ca/2014/03/versioning-rest-apis-with-定制accept.html

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

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

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

 @Path(/v2/ProductService) ProductServiceV2 extends ProductService { } @Path(/v1/ProductService) class ProductService{ } 

并且只会覆盖v2中更改的任何内容。 一切都保持不变,就像v1 / ProductService一样。

这明确地导致了更多的类,但只是一种更简单的编码方式,只需要在新版本的API中进行更改,并且在没有重复代码的情况下恢复到旧版本。