版本控制是一个复杂的话题,因此首先需要更具体地定义您的目标。尽管希望您的接口能确保不会破坏兼容性,但根据新功能是什么,这可能并不可能实现。因此存在不同的情况和不同的权衡。
如果您的意图仅是为新的使用者提供新的功能,并且所有使用者都是直接使用者(没有中介、框架等),那么离散的端点方法是最佳选择。每次添加一个有风险的特性时,创建一个新的端点,给它一个新的版本号,然后让使用者知道要对其进行验证并切换其配置。这种策略经过了充分的试验和验证,但是它也有缺点:使用者需要跟上更新的步伐。此外,如果服务之间存在依赖关系,跟踪它们可能会变得繁琐。好处是,如果代码出现问题,这不是(直接)你的错。
另一种主要策略是可扩展的接口。我知道有三种不同的类型。首先是试图很好地描述服务领域以使得任何可能的功能都可以在现有接口下实现的接口类型。如果这听起来很困难,那就是事实。您可能会称其为完美接口。一切都被完全描述了,但整个领域也被完全描述了。然而“完美”只存在于纸面上。
第二种类型看起来像普通的接口,但添加了通用的扩展点。在WSDL中,这意味着xs:any、名称-值对或类似的东西。您可以称之为基本可扩展接口。它不太难做到,但也不是没有其复杂性。扩展点可能使接口在某些工具中更难使用(如xs:any),或明确失去一些验证输入和输出的能力(名称-值对)。同时,很容易滥用这些扩展点,从而使第三或第四个版本变得非常难以使用。
第三种类型是将您的接口转换为字节流的类型。您可以称之为上帝接口。它们并不是没有正当理由,但如果您正在使用这种接口,您可能想问为什么要使用Web服务。也许您应该考虑原始的TCP/IP或基本的HTTP GET/POST。但也许您已经厌倦了WSDL和XSD的复杂性,只想从头开始,但因为某些基础结构的原因而被绑定到了Web服务上。然而,请注意,一旦您开始这条路,您将需要一个全新的方式来向您的消费者描述如如何/不如何使用您的服务,并且如果您使用XSD来做到这一点...那么您基本上回到了起点。我见过的最常见的策略是通过向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的这个链接提供了这种方法的基本原理,以及何时需要增加版本:我通常将版本字符串添加到Web服务URL中,从而创建“有版本的端点”。如果这些端点的差异很小且可以由相同的代码处理,则可以共享实现这些端点的代码,否则可以进行克隆,或者介于两者之间。
如果需要,不同的版本化端点还可以使用具有版本号的XML模式。
<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