21

我为我的客户提供了一个小型 Web 服务 API,我计划随着时间的推移对其进行改进。所以我需要某种版本控制,但我找不到有关您如何执行此类操作的任何信息。

有最佳实践吗?

如何在不破坏与 Web 服务使用者的兼容性的情况下不断添加新功能?

4

5 回答 5

20

版本控制是一个复杂的主题,因此首先,您需要以更具描述性的方式定义您的目标。可以说您有一个界面可以确保您永远不会破坏兼容性,但根据新功能是什么,这甚至可能是不可能的。所以有不同的情况和不同的取舍。

如果您的意图是只为新消费者提供新功能,并且您的所有消费者都是直接消费者(没有中介、框架等),那么离散端点方法是最佳选择。每次添加一个有中断风险的功能时,创建一个新的端点,给它一个新的版本号,然后让消费者知道要验证它并切换他们的配置。这种策略是经过验证的,也是正确的,但它的缺点是给消费者带来了跟上时代的负担。此外,如果服务之间存在依赖关系,则跟踪它可能会成为一件苦差事。好处是,如果代码中断,这不是(直接)你的错。

另一个主要策略是可扩展接口。我知道这里有三种不同的品种。首先,是一种接口类型,它试图很好地描述服务域,以至于在给定现有接口的情况下,您可能添加的每一个可能的功能都是可能的。如果这听起来很难,那就是。您可以称其为完美的界面。一切都被完整地描述了,但整个域也被完整地描述了。然而,“完美”实际上只是在纸上。

第二种是看起来像普通接口但添加了通用扩展点的类型。在 WSDL 中,这意味着 xs:any、名称-值对或类似的东西。您可以将其称为基本的可扩展接口。做起来并不难,但也不是没有并发症。扩展点可能会使接口在某些工具(xs:any)中更难使用,或者显式地失去一些验证输入和输出(名称-值对)的能力。滥用这些扩展点也很容易使版本 3 或 4 很难使用。

第三种是将您的接口转换为字节流的类型。你可以称这些为上帝接口。他们并非没有理由,但如果您正在使用其中一个,您可能想问一下您为什么要使用 Web 服务。也许您应该考虑原始 TCP/IP 或基本 HTTP GET/POST。但是,也许您已经厌倦了 WSDL 和 XSD 的复杂性,并且只想从头开始,但由于某些基础设施原因,您与 Web 服务相关联。然而要意识到,一旦你开始走这条路,你将需要一种全新的方式来向你的消费者描述如何/不使用你的服务,如果你为此使用 XSD ......好吧,你基本上回到了哪里你开始了。

您最好的选择是了解所有这些选项并通过首先尝试“完美界面”来处理您的服务设计,然后放弃并添加通用可扩展点。尝试设计完美的界面将迫使您学习可以使您的服务更好的东西,而不仅仅是您的界面,但这需要时间,如果您不以某种方式限制时间,那将需要永远。

有点少了一个真神接口,还有包装接口。如果你的系统有层,你希望你的界面也有层。当您更改 B 层时,您只想更改 B 层,而不是 C 层中的所有实例。

于 2009-11-08T02:23:59.767 回答
8

我见过的最常见的策略是通过将版本标识(通常yyyy/MM[/dd])添加到 wsdl 中对象的命名空间来对 WSDL 进行版本控制,即:

targetNamespace="http://schemas.mycompany.com/2010/01/widgets"

这可以在每个type( types/schema) 级别或整个 WSDL 级别(<definitions>在 1.1 或<description>2.0 中)完成。

有点过时了,但是IBM Developer Works 的这个链接提供了这种方法的基本原理,特别是在需要增加版本时:

向后版本兼容/非破坏性更改:

  • 添加新操作
  • 添加新类型

重大变化:

  • 删除或重命名操作
  • 将参数更改为方法
  • 更改复杂类型
于 2013-09-25T13:18:23.710 回答
3

我通常将版本字符串添加到 Web 服务 URL,给我“版本化端点”。如果差异很小并且可以由相同的代码处理,则可以共享实现这些端点的代码,或者可以克隆代码,或者介于两者之间。

如果您需要的话,不同版本的端点也可以使用版本化的 XML 模式。

于 2009-11-05T09:40:16.673 回答
1

其中一种可能性是将所有 Web 服务操作设计为只有一个类型的参数,该类型继承自包含版本号的某个抽象类型。这种方法是由eBay 网络服务平台实现的。类似于以下内容:

<xsd:complexType name="AbstractRequestType">
  <xsd:attribute name="version" type="string" />
  ....

<xsd:complexType name="AddCustomerRequestType">
  <xsd:complexContent>
   <xsd:extension base="AbstractRequestType">
   ....

then use AddCustomerRequestType as a type of only parameter 
in addCustomer web service operation.

此外,如果您使用 http,您可能需要将版本作为 http GET 参数添加到 Web 服务端点 url,这样您就可以轻松检测请求的版本 http://server/service?version=1

于 2009-11-09T17:03:22.550 回答
1

在所有 API 中添加“API 版本号”作为参数,然后在您的 Web 服务代码中实施策略模式,其中版本号指示要使用的策略。

于 2009-11-05T09:36:11.347 回答