Web服务API版本控制

21
我向我的客户提供一个小型Web服务API,我计划随着时间的推移进行改进。因此,我需要某种形式的版本控制,但我找不到有关如何做此类事情的任何信息。是否有最佳实践?如何在不破坏Web服务消费者的兼容性的情况下继续添加新功能?
5个回答

21

版本控制是一个复杂的话题,因此首先需要更具体地定义您的目标。尽管希望您的接口能确保不会破坏兼容性,但根据新功能是什么,这可能并不可能实现。因此存在不同的情况和不同的权衡。

如果您的意图仅是为新的使用者提供新的功能,并且所有使用者都是直接使用者(没有中介、框架等),那么离散的端点方法是最佳选择。每次添加一个有风险的特性时,创建一个新的端点,给它一个新的版本号,然后让使用者知道要对其进行验证并切换其配置。这种策略经过了充分的试验和验证,但是它也有缺点:使用者需要跟上更新的步伐。此外,如果服务之间存在依赖关系,跟踪它们可能会变得繁琐。好处是,如果代码出现问题,这不是(直接)你的错。

另一种主要策略是可扩展的接口。我知道有三种不同的类型。首先是试图很好地描述服务领域以使得任何可能的功能都可以在现有接口下实现的接口类型。如果这听起来很困难,那就是事实。您可能会称其为完美接口。一切都被完全描述了,但整个领域也被完全描述了。然而“完美”只存在于纸面上。

第二种类型看起来像普通的接口,但添加了通用的扩展点。在WSDL中,这意味着xs:any、名称-值对或类似的东西。您可以称之为基本可扩展接口。它不太难做到,但也不是没有其复杂性。扩展点可能使接口在某些工具中更难使用(如xs:any),或明确失去一些验证输入和输出的能力(名称-值对)。同时,很容易滥用这些扩展点,从而使第三或第四个版本变得非常难以使用。

第三种类型是将您的接口转换为字节流的类型。您可以称之为上帝接口。它们并不是没有正当理由,但如果您正在使用这种接口,您可能想问为什么要使用Web服务。也许您应该考虑原始的TCP/IP或基本的HTTP GET/POST。但也许您已经厌倦了WSDL和XSD的复杂性,只想从头开始,但因为某些基础结构的原因而被绑定到了Web服务上。然而,请注意,一旦您开始这条路,您将需要一个全新的方式来向您的消费者描述如如何/不如何使用您的服务,并且如果您使用XSD来做到这一点...那么您基本上回到了起点。
最好的选择是了解所有这些选项,并首先尝试实现"完美接口",然后放弃并添加通用可扩展性点。试图设计完美的接口将迫使您学习东西,这将使您的服务变得更好,不仅是您的接口,但这需要时间,如果您不以某种方式限制时间,它将永远持续下去。
略微不及真正上帝接口的是包装器接口。如果您的系统具有层,则希望您的接口也具有层。当您更改B层时,您只想更改B层,而不是所有C层中的实例。

2
对我来说,这些都有点抽象和空中楼阁。 - Tim Abell
4
在原问题所提供的信息下,他应该如何表述得最具体? - Dave
存在第四种变体,我时常遇到:软版本控制,当服务器需要通过响应提供更多数据点时,它可以正常工作。这可以通过客户端请求指示其使用新版本来安全地完成。其他人也通过让API的客户端在某些设置页面上配置其可以容忍的新字段来提供此功能。后者更容易出错,而且更难测试。 - Rickard S

8

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

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

这可以在每个type(types/schema)级别或整个WSDL级别(1.1中的<definitions>或2.0中的<description>)进行。虽然有点过时,但IBM Developer Works的这个链接提供了这种方法的基本原理,以及何时需要增加版本:
向后版本兼容/非破坏性更改:
- 添加新操作 - 添加新类型
破坏性更改:
- 删除或重命名操作 - 更改方法的参数 - 更改复杂类型

3

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

如果需要,不同的版本化端点还可以使用具有版本号的XML模式。


2
其中一种可能性是设计所有 Web 服务操作只有一个参数,该参数是从某个抽象类型继承版本号的类型。这种方法是由 eBay web services platform 实现的。 类似以下内容:
<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


1
在所有的API中添加“API版本号”作为参数,然后在您的Web服务代码中实现策略模式,其中版本号决定使用哪种策略。

5
只有当版本化的Web服务接受完全相同的参数时,才能起作用,因此相同的WSDL适用。如果新版本需要添加新属性,该怎么办? - Stella Peristeraki

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接