我向客户提供了一个小型Web服务API,我计划随着时间的推移而发展。所以我需要某种版本控制,但是我找不到任何关于你是如何做这样的事情的信息。
有最好的做法吗?
如何在不破坏与Web服务使用者的兼容性的情况下继续添加新功能?
答案 0 :(得分:19)
版本控制是一个复杂的主题,因此首先,您需要以更具描述性的方式定义目标。很高兴地说你有一个接口可以确保你永远不会破坏兼容性,但是根据新功能的不同,这可能是不可能的。所以有不同的情况和不同的权衡。
如果您的目的是仅向新消费者提供新功能,并且您的所有消费者都是直接消费者(没有中间人,框架等),那么离散终端方法是最佳选择。每次添加可能存在中断的功能时,请创建新端点,为其指定新版本号,然后让消费者知道对其进行验证并切换其配置。这种策略非常有效,但它的缺点是让消费者承担更新的负担。此外,如果服务之间存在依赖关系,它可能成为一项需要跟踪的工作。如果代码破坏它的好处不是(直接)你的错误。
另一个主要策略是可扩展接口。我知道这里有三种不同的品种。首先,是尝试如此好地描述服务域的接口类型,在给定现有接口的情况下,您可能添加的每个可能功能都是可能的。如果这听起来很难,那就是。你可以称之为完美的界面。一切都完全描述,但整个领域也完全被描述。 “完美”实际上只是纸上谈兵。
第二种是看起来像普通界面但添加通用扩展点的类型。在WSDL中,这意味着xs:any,name-value对或类似的东西。您可以将其称为基本可扩展接口。这并不难,但并非没有它的复杂性。扩展点可能使界面更难以在某些工具(xs:any)中使用,或者明显失去一些验证输入和输出(名称 - 值对)的能力。以一种使版本3或4很难使用的方式滥用这些扩展点也很容易。
第三种是将您的接口转换为字节流的类型。你可以称这些神接口。他们并非没有理由,但如果你使用的话,你可能会想问为什么你要使用网络服务。也许您应该考虑原始TCP / IP或基本HTTP GET / POST。但是,您可能厌倦了WSDL和XSD的复杂性,而您只是想从头开始,但出于某些基础设施原因,您需要依赖Web服务。但要意识到,一旦你开始走这条道路,你将需要一种全新的方式向你的消费者描述如何/不使用你的服务,如果你使用XSD那么......你基本上回到了哪里你开始了。
您最好的选择是了解所有这些选项并首先尝试“完美界面”,然后放弃并添加通用扩展点来实现服务设计。试图设计完美的界面将迫使你学习能使你的服务更好的东西,而不仅仅是你的界面,但这需要时间,如果你不以某种方式限制时间,它将需要永远。
有点真正的神界面,有包装界面。如果您的系统有图层,您希望您的界面也在图层中。更改图层B时,您只想更改图层B,而不是图层C中的所有实例。
答案 1 :(得分:8)
我见过的最常见的策略是通过向wsdl中的对象命名空间添加版本标识(通常为yyyy/MM[/dd]
)来版本化WSDL,即:
targetNamespace="http://schemas.mycompany.com/2010/01/widgets"
这可以在每{ - 1}}(type
)级别或整个WSDL级别 - 1.1中的types/schema
或2.0中的<definitions>
中完成。
有点过时,但IBM Developer Works的this link提供了这种方法的基本原理,特别是当需要增加版本时:
向后版本兼容/不间断更改:
重大改变:
答案 2 :(得分:3)
我通常会将版本字符串添加到Web服务URL,为我提供“版本化端点”。实现这些端点的代码可以共享,如果差异很小,可以由相同的代码处理,或者代码可以克隆,或者介于两者之间。
不同版本化的端点也可以使用版本化的XML Schema,如果这是你需要的。
答案 3 :(得分:1)
在所有API中添加“API版本号”作为参数,然后在您的Web服务代码中实现策略模式,其中版本号决定了要使用的策略。
答案 4 :(得分:1)
其中一种可能性是将所有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