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

Dee*_*h M 45 java rest jax-rs resteasy

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

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

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

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

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

我已经考虑过使用不同的@Path注释定义资源类的方法,例如,在该包的ProductsResource类中单独包含v1和v2的包,定义

    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 {...}
Run Code Online (Sandbox Code Playgroud)

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

怎么写自定义注释说@Version并拥有它支持的版本的值?现在无论是v1还是v2,两个请求都将转到相同的资源类.

比如说

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

更新:

Jarrod有一个API版本控制建议来处理标题中的版本.这也是一种方法,但我期待在遵循基于URI的版本控制时使用最佳实践

小智 16

将其放入URL中的问题是URL应该按位置表示资源.API Version不是位置,也不是资源标识符的一部分.

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

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

将它放在Accept:你想要的标题的mime类型中.就像是Accept: application/myapp.2.0.1+json

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

  • 示例:我的用户帐户是SO上的资源.网址是:http://stackoverflow.com/users/322722/cmonkey.当/如果SO更改功能,apis或向我的用户帐户添加数据时,该帐户仍然是相同的资源.它不会突然变成http://.../cmonkey_v2.否则,链接的内容(如此评论)将不再有效. (5认同)
  • 接下来 - 在RESTful应用程序中,您的URL应该代表一个资源.资源可能不是'版本化'; 无论访问风格如何,它都是一样的.如果资源_is_版本化,则应在资源内表示,而不是在其标识符中表示. (4认同)
  • 在真正的RESTful环境中,保留版本控制构造的位置或URI的设计方式无关紧要.RESTful客户端除了其起始URI之外没有关于服务的信息.其他一切都是通过请求和回复来学习的.如果发生版本控制更新,则客户端仍在请求与之前使用的相同的起始URI.然而,服务器现在返回不同的东西.如果内容类型保持不变并且仅略微改变了URI,则客户端可能甚至不会注意到很大的差异. (2认同)

Dav*_*sot 11

这篇博文有一个例子,其中一些被认为是正确的方法,即没有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"})
Run Code Online (Sandbox Code Playgroud)

  • 谁定义了什么被认为是正确的道路?REST是一种架构风格,没有协议!除非您违反HTTP或不遵守[架构约束](https://en.wikipedia.org/wiki/Representational_state_transfer#Architectural_constraints),否则没有对错,也许是一些最好的做法,尽管一些自称的REST服务不是以任何方式RESTful,因此应特别小心对待某些陈述. (3认同)