2009-11-05 87 views
15

我为我的客户提供了一个小型的Web服务API,我打算随着时间的推移而发展。所以我需要某种版本控制,但是我找不到任何关于如何做这种事情的信息。Web服务API版本

是否有最佳做法?

如何不断开添加新功能而不破坏与Web服务使用者的兼容性?

回答

0

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

+4

这样的工作只有在版本的Web服务需要*准确*的相同的参数,所以相同的WSDL适用。如果在新版本中需要增加一个新属性,你会怎么做? – 2009-11-05 10:57:03

1

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

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

18

版本控制是一个复杂的主题,首先,您需要以更具描述性的方式定义您的目标。很高兴地说,你有一个接口可以确保你永远不会破坏兼容性,但取决于新功能是什么,这可能甚至是不可能的。所以有不同的情况和不同的权衡。如果您的意图是仅向新消费者提供新功能,并且您的所有消费者都是直接消费者(无中间人,框架等),那么离散终端方式是最佳选择。每次添加可能会中断的功能时,请创建一个新端点,并为其指定一个新版本号,然后让消费者知道对其进行验证并切换其配置。这种策略相当有成效,但存在消费者负担不断增加的缺点。另外,如果服务之间存在依赖性,它可能成为一件难事。如果代码被打破,它不会(直接)成为你的错。

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

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

第三种是将接口转换为字节流的类型。你可以称这些神界面。他们并非没有理由,但如果你使用了一个,你可能会问为什么你使用网络服务。也许你应该考虑原始的TCP/IP或基本的HTTP GET/POST。但是,也许你厌倦了WSDL和XSD的复杂性,你只是想从头开始,但是出于某些基础设施的原因,你被绑定到了Web服务。然而,要意识到,一旦你开始了这条道路,你需要一种全新的方式来向消费者描述如何/不使用你的服务,如果你使用XSD,那么你基本上就回到了那里你开始了。

最好的选择是通过首先尝试“完美界面”,然后放弃并添加通用扩展点,来了解所有这些选项并接近您的服务设计。试图设计完美的界面将迫使你学习能让你的服务更好的东西,而不仅仅是你的界面,但这需要时间,而且如果你不以某种方式限制这个时间,它将会持续下去。

有点缺乏真正的神界面,有包装界面。如果您的系统具有图层,则您希望您的界面也处于分层状态。当您更改图层B时,您只想更改图层B,而不是图层C中的所有实例。

+1

所有的一些抽象和天空饼为我喜欢。 – 2011-05-17 14:18:59

+4

考虑到原始问题中提供的信息,他究竟应该如何确定最具体的? – HDave 2012-01-13 02:20:04

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

5

是我见过的最常见的策略是版本的WSDL加入版本识别(通常yyyy/MM[/dd])对象的WSDL中的命名空间,即:

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

这可以在每个typetypes/schema)级别完成,也可以在整个WSDL级别完成,即1.1或<description>(2.0)中的<definitions>

有些过时,但是从IBM开发this link工作提供了这种方法的基本原理,以及特别是当版本需要递增:

向后版本compatable /非破坏性变更:

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

重大更改:

  • 删除或重命名操作
  • 更改参数的方法
  • 更改复杂类型