用于版本控制外部 API 的 Java 包命名

Posted

技术标签:

【中文标题】用于版本控制外部 API 的 Java 包命名【英文标题】:Java package naming for versioning external APIs 【发布时间】:2017-08-11 13:33:06 【问题描述】:

对于如何命名包含使用外部版本化 API 的类的 Java 包是否有任何约定?

假设我们有一个服务的主要-次要语义版本控制方案,我们必须实现一个与该 API 的特定版本兼容并绑定到该 API 的使用者。命名包(和类)的最佳做法是什么?

目前,我们使用的方案是:$service_$M_$N(M = 主要版本,N = 次要版本)。例如:com.example.theService_1_0.。 但是 sonarqube 抱怨它不符合惯例。 当然我可以禁用这条规则,但我想知道是否有任何最佳实践?

我正在寻找一种通用方法,而不仅仅是针对 REST 的方法,因为我遇到了 WebService、REST 和 CORBA 的消费者实现。而且我不确定,artifact-versioning(如在 maven 中)在这里效果很好,因为它与实现的版本有关,而不是 API。

我知道有关于 api versioning 的问题,但这些问题是关于生产者,而不是消费者。

【问题讨论】:

这是否意味着潜在的不必要的代码重写。每次生产者更改版本时,您都需要更改包名称以及使用该类的所有类中的所有导入语句。 我在一些项目(金融行业)中看到,它们只是将它们并排放置(以重复代码为代价),并分别维护消费者,因此更改为一个消费者版本 impl不影响另一个 impl。当一个新版本出现时(这是几年的事情),他们首先复制现有的代码。它基本上是一种无共享的方法。这当然是一种务实的做法,但我想知道是否有任何(更好的?)替代方案? 我不会在目标 API 版本之后命名包。您的项目应该声明对给定 API 版本的依赖项,并且每次您想要针对不同的 API 版本(即,当您更改依赖项版本时)时,您只需使用自己的版本号对项目进行版本控制。例如:myproject 版本 1.1 .8 使用 api 版本 2.3.0 ,myProject 版本 1.2.0 使用 api 版本 2.4.6 。 @Berger,如果 API 可以作为可以检查的依赖项(即 maven)使用,那将起作用。但假设情况并非如此(即 http、wsdl、corba/idl)。如果您在同一个应用程序中使用两个 API 版本的一部分,这将变得特别棘手(这不是一个假设的例子,我在现实生活中已经看到了) 我知道这是一个旧线程,但我在这里是因为我试图弄清楚如何处理支持 API 的并行版本。在我的用例中,供应商的 API 大约每季度更改一次。有时更改是破坏性更改。我的应用程序需要支持与客户端在其环境中的任何版本的集成,因此我认为我需要将版本视为配置选项并提供某种切换到不同的底层逻辑。大部分客户端代码实际上都可以生成,所以代码开销不是主要因素。 【参考方案1】:

是的,Java 包名称具有用于指示依赖项版本的强而模糊的约定:不要

如果您更改应用程序以使用新版本的外部 API,您将创建一个新版本的应用程序。您要查找的版本号是您的应用程序的版本号。在许多 Java 项目中,依赖项的版本由 Maven 配置文件管理。

在任何情况下,当类使用特定的 API 版本时,类名和包名都不会暴露这些信息,这将违反封装,除此之外。这些名称有不同的用途。

请注意,这在您使用 HTTP/REST API 或 Java API 时没有什么不同。毕竟,我认为您不会将您的班级命名为TheServiceWithLog4J_12_1_5。至少我希望不会。

您没有提到是否需要同时支持此外部 API 的多个版本。即使你这样做了,我仍然不建议在包名称中公开 API 版本号。相反,请使用包名来说明为什么你有两个版本,以及重要的区别。

【讨论】:

以上是关于用于版本控制外部 API 的 Java 包命名的主要内容,如果未能解决你的问题,请参考以下文章

使用内联命名空间的 API 版本控制

利用Anaconda进行包版本控制

Web-API 版本控制不适用于默认版本

Web api dotnet core 中的 Api 版本控制错误的自定义错误响应

.Net 核心版本控制:文件夹结构/命名空间

带有 IHttpControllerSelector 的 AttributeRouting - Api 版本控制