15

所以我对 Web 服务有点陌生,最近出现了一种情况,我们向返回给客户端的数据类型添加了一个元素。客户抱怨这破坏了他们的实施,因为它阻塞了它没想到的新元素。(我们通过 Axis2 提供服务)。

对我来说,这似乎是一个无害的更改,客户端应该能够优雅地处理(我使用过一些非 Web 服务框架,在这些框架中添加可选信息是完全可以接受的)。如果我们删除或重命名了一些会导致客户出现问题的字段,我可以理解。

基本上我希望 wsdl 像一个接口一样工作。如果我们进行实质上为该接口子类型的更改,我希望客户端会愉快地忽略无关元素。这只是 Web 服务的一个短板,还是有一种理智的方式对服务进行被动更改,以便新客户可以获得额外的数据,而老客户可以在闲暇时更新?

4

4 回答 4

10

WSDL 实际上充当契约而不是接口。WSDL 准确地描述了操作期望“接收”什么以及期望“返回”什么。与此最接近的类比是在 C 中更改函数的原型而不更改函数本身,它们不会匹配并且会导致问题。

WSDL 越具体,您“保证”到位的行为就越多。

如果您需要返回数据的灵活性(即添加/删除字段等),您可以执行以下操作之一:

  1. 版本化您的 WSDL 定义并发布可以将旧版本重定向到新版本的服务
  2. 使用更抽象的数据返回类型,例如 XML 来隐藏复杂性或变化的数据。

2 有更多风险,但可以使用 XSD 或其他技术进行管理。您的特定项目要求将决定什么是可接受的。

于 2009-12-17T20:14:48.303 回答
4

过去,在处理暴露的 WebService API 时,我总是采用日期版本控制理念。不幸的是,一旦您退出“测试版”模式(有时甚至是这样),您就必须处理向公众发布的任何 API 的向后兼容性。

我们所做的非常简单;在新 API 发布当天,我们将创建一个文件夹结构,如下所示:

http://mydomain.com/path/to/service/2009/12/17/servicename.svc

这样,我们只需检查文件夹结构就可以知道哪个版本是最新的,并且我们的客户在准备升级之前不必担心破坏性更改。对我们来说像冠军一样工作;我唯一可能改变的是使用一个文件夹,这样它们就更容易一起查看:

http://mydomain.com/path/to/service/2009-12-17/servicename.svc
于 2009-12-17T20:11:50.883 回答
4

WSDL 实际上是您发布的 Web 服务的 SOAP 接口。许多客户使用它来生成他们的客户端代理,这些代理以他们选择的编程语言公开您的所有 Web 服务方法。大多数这些代码生成的客户端都非常脆弱,如果他们看到一个他们无法识别的元素(即它不在 WSDL 中),他们会选择抛出异常而不是忽略它。有些人更轻松,这实际上取决于他们使用的客户端技术,即微软的新 DataContract 在他们的客户端上有 IExtensibleData 接口来专门保存他们无法识别的数据,因此他们将在很大程度上忽略未知元素。

SOAP 和代码生成的客户端代理很容易解决这类问题,因为它们生成的客户端想要理解“整个模式”,而不仅仅是他们感兴趣的部分。另一种方法是让他们使用 Xml 解析器并拉取拿出他们需要的东西。

如果您的 Web 服务正在开发或不断更改,那么 SOAP 确实不是您的最佳选择,因为这意味着每次更改都必须重新生成、重建和重新部署其服务客户端。根据您的情况,您可能需要考虑提供 REST+POX (Plain Old Xml) Web 服务,因为它更易于解析,因为它没有 SOAP 的开销,可以通过普通 URL 调用并由环境使用没有 SOAPClient 库(例如直接在浏览器中,使用 AJAX)

于 2010-02-09T10:01:12.510 回答
0

一种可能的答案是使用替换组来启用您导入的 XSD 中的抽象模型。处理此类替换组的可能性仍需使用您用来调用这些服务的框架进行验证。

于 2014-05-13T12:07:11.833 回答