0

我们将 REST Web 服务视为一种“面向未来”我们的业务的方式,等等。我正在考虑对 REST Web 服务进行版本控制的各种方法的权衡,我想了解其他人在对 REST Web 服务进行版本控制时学到了什么。

关于 SO 和其他地方有很多关于版本控制 Web 服务的很好的讨论,但大多数都集中在是否将版本号放在 URL 或请求标头中。

版本控制 Web 服务有多个方面。在 Web 服务调用本身(URL 或标头)中指定了版本。在源代码中管理多个版本的业务逻辑。正在构建版本化的 Web 服务。存在版本控制问题。还有如何弃用和删除过时版本的问题。

我们正在编写移动客户端的合作伙伴希望将版本放在 URL 中,这就是我的方法(目前)。此外,这些网络服务的新版本可能与旧版本不兼容。例如,不同版本中可能有不同的安全实现。

当涉及到版本化 URL 时,通常建议使用两种方法 - 将版本号放在 URL 中或将其作为参数

context-root/service/rest/v0.1/restMethod/param1

context-root/service/rest/restMethod/param1?version=v0.1

第二种方法需要一些控制器逻辑来将请求路由到正确的实现,但这并不难。两者之间的选择并不难。

第三种选择是将版本号放在上下文根本身中,这意味着将其放在 .war 文件名前缀或部署描述符中:

restarchive-v0.1/service/rest/restMethod/param1

这意味着为当前支持的所有版本部署多个档案。

我喜欢在文件名中包含版本号。它使查看部署的内容变得容易。这种方法的缺点是它需要为每个版本化存档单独构建,可能使用 maven 配置文件。

这是第一种方法的代码的样子。每个 Web 方法都为该方法的所有受支持版本执行其自己的控制器逻辑。每个版本的业务逻辑都可以以一种明智的方式处理(即在包中放入版本号)。

    @ApplicationPath("/service/rest")
    @Path("/{version}/")
    public class RestService extends Application {

    @GET
    @Path("/user/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public User getUser(@PathParam("version") String version, @PathParam("id") int id) {

        User user;
        if (version.equals("v0.1")) {
            //  call v0.1 code to get the User
         }
         else if (version.equals("v0.2")) {
            //  call v0.2 code to get the User
         }
         else {

             throw new WebApplicationException(Response.Status.NOT_FOUND);
         }

         return user;
    }

}

我的第一个实现在不同的包中使用了 javax.ws.rs.core.Application 的多个子类,包中的版本号。这应该可以,但是 JBoss RESTeasy 实现不允许在一个 .war 中使用多个 Application 子类。这显然违反了 JAX-RS 1.1 规范,但如果您使用 JBoss 或 RESTeasy,您将不得不忍受这种限制。

我倾向于将第一种方法与上述类似的实现一起使用。由于我正在努力尽量减少未来的问题,我想听听其他人通过版本 Web 服务的各个方面的经验学到了什么。

这是一种合理的方法,还是会导致我在这里没有提到的问题?

4

1 回答 1

0

这个话题是在 JavaOne 上提出来的,并没有正确的答案。

提供该演示文稿的人说,他的偏好是将版本保留在标题中,并避免将其放在 URL 中或作为查询参数。

就个人而言,我们自己对文件进行版本控制。无论如何,我们必须部署单独的版本化构建,所以它没有太多额外的麻烦。我们只是从 Manifest 中提取版本号并将 ?{version} 附加到文件中。

于 2012-10-05T19:32:22.560 回答