【问题标题】:Strategies for updating or versioning web services?更新或版本控制 Web 服务的策略?
【发布时间】:2010-10-30 04:31:04
【问题描述】:

我很想听听有关如何处理不同版本的 Web 服务的最佳做法。

澄清一下,如果您将一些 Web 方法公开为 Web 服务,那么您想要添加特性/功能并因此更改这些方法调用的签名,您如何以不t 中断当前调用该服务的所有客户?

您是否将服务部署在不同的 URL 上?

您是否在方法名称本身中添加了一个版本(MyMethod、MyMethodv2 等 - 呃..)

您是否将版本作为方法调用的一部分与参数列表一起传递?

有谁知道 Google 或 Amazon 如何使用其广泛的 Web 服务库来处理这种情况?

编辑:到目前为止,我在article from Oracle 中找到了一些很好的信息。 this blog entry 在一些 Java 细节上也很有用。我仍然很想看看其他一些方法。

【问题讨论】:

标签: .net web-services deployment


【解决方案1】:

我可以告诉你,创建 doAPIFunction、doAPIFunctionV2 和 doAPIFunctionV3 等的解决方案在我工作的地方只会让人头疼。再加上缺乏清晰描述的函数名称意味着各种疯狂。

您需要清晰的 API 函数名称,如果 api 发生变化,目标是尝试以尽可能向后兼容的方式这样做。我建议对您的入口点进行版本控制,以便每个入口点都支持稳定的 API,如果有充分的理由更改语义,example.org/api-1.0/ 中的 doFunction 可能与 example.org/api-2.0 不同。

【讨论】:

    【解决方案2】:

    我不确定我是否正确理解了您的问题。但是我的2美分。 如果方法的签名像另一个新参数一样更改,那么为什么不能将其设为可选?但是如果现有的参数数据类型发生了变化,那么它就不适用了。

    如果它完全错误,请投反对票。 :)

    【讨论】:

    • 这个问题应该回应你的回答,因为你是否可以使用可选参数取决于你的语言是否支持它。 bytes.com/groups/net-c/730388-web-service-optional-parameters
    • @James,这是一个很好的链接。正如那个论坛指出的那样,为什么马特不能尝试重载?
    • Web 服务不支持可选参数或重载,因此您使用的语言无关紧要。
    【解决方案3】:

    几年前,当您可以拥有相同的 Web 服务方法名称和不同的参数时,它曾经更简单。 :)

    一旦您编写了 Web 服务,您就与客户签订了一份合同,这就是您将支持的内容。

    对于较旧的方法,我建议记录以查看它们是否正在使用以及由谁使用,以查看是否可以让它们更新。

    除此之外,您最好只编写一个新方法,因此您可能有几个相似的函数名称,但版本不同。

    传入版本号的问题在于,您必须确保客户端始终传入一个有效的数字,如果您生成存根,它会起作用,但如果您不这样做,那么这是非常脆弱的。

    在名称中加上版本号似乎对我来说效果最好,因为它可以让旧版本一目了然,并且您可以使用 AOP 更轻松地记录旧版本的 Web 服务方法。

    【讨论】:

      【解决方案4】:

      缓解这种情况的一种方法是按合同编写代码并设置接口。您永远无法真正更改函数签名,但是您可以重载它们。考虑 .NET API。它弃用了一些方法,但它们继续工作,因为围绕它们编码的程序可能会中断。新版本的服务可能会以不同的 URI (v2.webservice.com) 公开,以提供新的路线图,并且需要继续支持 v1。

      【讨论】:

      • 感谢您的回答,但我的问题更多是关于如何在生产中处理 Web 服务的版本控制。例如,如何运行 MyWebMethod(int i, int x) 和 MyWebMethod(int i, int x, int y) 并在部署中处理这个问题。我们确实在所有编码项目中将 SVN 用于我们的 VCS。
      【解决方案5】:

      对 Web 服务进行版本控制的典型方法是让客户端指定所需的版本。您可以允许简单的约束,例如“>2.0”、“

      提供版本的技术各不相同。有些人提倡使用 URL,有些人鼓励使用标头,有些人可能会将其作为 api 调用的参数。不过,几乎没有人会更改方法的名称。这相当于 OSGi 链接谈到的“包”或“命名空间”版本。这将使升级变得非常困难,并且比对实际服务的任何更改更阻碍人们升级。

      这还取决于您访问网络服务的方式。如果您使用的是 REST,那么保持 URL 的干净并使用标头是最有意义的(如果需要,将其作为查询参数破解是微不足道的)。如果您使用的是 SOAP/XMLRPC/whatever-RPC,则通常将其放在 URL 中即可。

      编辑 5/2011 FWIW,尽管我不同意,Apigee's blog recommends putting the version in the URL

      客户端如何指定版本通常非常简单。更复杂的是如何同时运行所有版本。大多数语言没有办法将同一个库/模块/类/函数的多个版本加载到同一个运行时环境(无论是 VM、进程还是您拥有的)。您提供的 OSGi 链接是 Java 允许这样做的解决方案。

      在实践中,OSGi 在大多数情况下都过分了。将不推荐使用的请求代理到另一个服务器或进程通常更容易。

      不过,对您的服务进行“版本化”的最佳方式是在其中构建可扩展性和灵活性,以便它们保持向前和向后兼容。这并不意味着所有版本都必须相互兼容,而是连续的版本应该相互兼容。

      【讨论】:

      • +1 - 很好的答案。感谢您的洞察力。我们正在使用 SOAP 连接到 Oracle/Java 服务。
      • REST 和 RPC 的区别很有趣。很有见地。
      • 在 URL 中还是在命名空间中?
      • 约翰,你所说的“命名空间”是什么意思?如果它是 URL 路径的一部分,那么我通常不同意它。
      猜你喜欢
      • 2019-04-07
      • 2021-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多