简体   繁体   English

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

[英]Best way to handle JAX-RS REST API URI versioning

I did my search first in stackoverflow & I was not able to find out any answers related to my question. 我首先在stackoverflow中进行了搜索,但我无法找到与我的问题相关的任何答案。 All I can find was questions related to REST uri design. 我能找到的只是与REST uri设计相关的问题。

My question in on the backend side. 我在后端的问题。 Suppose we have two different version of REST uri's 假设我们有两个不同版本的REST uri

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

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

What is the best approach to follow on the backend side (server side code) for proper routing, manageability & reuse of the existing classes across these two set of api's based on version? 在后端方面(服务器端代码)遵循基于版本的这两组API的正确路由,可管理性和现有类的重用的最佳方法是什么?

I have thought of approach to define resource classes with different @Path annotations for eg have a package for v1 & v2 separately & in ProductsResource class of that package, define 我已经考虑过使用不同的@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 {...}

& then have the implementation logic based on the versions. 然后有基于版本的实现逻辑。 The problems with this approach is when we are only changing one particular resource api from the set of api's, we have to copy other classes to the v2 package also. 这种方法的问题是当我们只从api集合中改变一个特定的资源api时,我们也必须将其他类复制到v2包中。 Can we avoid it? 我们能避免吗?

How about to write a custom annotation say @Version & have values of the versions it supports? 怎么写自定义注释说@Version并拥有它支持的版本的值? Now whether it is v1 or v2, both request will go to same resource class. 现在无论是v1还是v2,两个请求都将转到相同的资源类。

Say for eg 比如说

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

UPDATE: 更新:

There was a API versioning suggestion by Jarrod to handle version in headers. Jarrod有一个API版本控制建议来处理标题中的版本。 That's also one way to do it however, I am looking forward for best practices to use when we are following URI based versioning 这也是一种方法,但我期待在遵循基于URI的版本控制时使用最佳实践

The problem with putting it in the URL is that the URL is supposed to represent a resource by location. 将其放入URL中的问题是URL应该按位置表示资源。 An API Version is not a location and it not part of the identifier of the resource. API Version不是位置,也不是资源标识符的一部分。

Sticking /v2/ in the URL breaks all existing links that came before. URL中的Sticking /v2/会破坏之前的所有现有链接。

There is one correct way to specify API versioning: 有一种正确的方法可以指定API版本控制:

Put it in the mime-type for the Accept: header that you want. 将它放在您想要的Accept:标头的mime-type中。 Something like Accept: application/myapp.2.0.1+json Accept: application/myapp.2.0.1+json

Chain of Responsiblity pattern goes well here especially if there will be significant number of API versions that are different enough to have to have their own handler, that way methods don't get out of hand. 责任链模式在这里很顺利,特别是如果有大量的API版本不同,必须拥有自己的处理程序,这样方法就不会失控。

This blog post has an example of what is considered the by some to be the correct approach, ie not having the version in the URI: http://codebias.blogspot.ca/2014/03/versioning-rest-apis-with-custom-accept.html 这篇博文有一个例子,其中一些被认为是正确的方法,即没有URI中的版本: http//codebias.blogspot.ca/2014/03/versioning-rest-apis-with-定制accept.html

In short, it leverages JAX-RS @Consume annotation to associate the request for a particular version to a specific implementation, like: 简而言之,它利用JAX-RS @Consume注释将特定版本的请求与特定实现相关联,例如:

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

I was just wondering why not have a subclass of ProductService called 我只是想知道为什么没有调用ProductService的子类

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


}


@Path(/v1/ProductService)
 class ProductService{


}

and only override whatever is changed in v2. 并且只覆盖v2中更改的内容。 Everything unchanged will work the same as in v1/ProductService. 所有未更改的内容与v1 / ProductService中的相同。

This defintely leads to more # of classes but is one easier way of coding for only whatever is changing in the new version of api and reverting to the old version without duplicating code. 这绝对会导致更多的类,但是只有一种更简单的编码方式,只需要在新版本的api中进行更改,并在没有重复代码的情况下恢复到旧版本。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM