【问题标题】:Would using a WSDL to generate REST clients be the wrong direction?使用 WSDL 生成 REST 客户端会是错误的方向吗?
【发布时间】:2011-01-19 20:10:43
【问题描述】:

我打算创建一个相当简单的 Web 服务供 Intranet 使用。该服务最终将成为数据库的接口,使我能够跟踪公司内部的各种内部工具正在做什么。我想我想要一个 Web 服务,以便组织内的各种工具(以及不同的语言)可以轻松更新数据库,而无需知道架构。

我已经阅读了许多通过搜索 https://stackoverflow.com/search?q=soap+rest 提出的相关 REST 与 SOAP 问题,但我不确定我是否找到了答案。

我的困境似乎是我想要 REST 的简单性,同时还拥有 WSDL 的代码生成能力,这似乎暗示了 SOAP。对我来说最重要的是,各种内部工具(JAVA、Perl、Python、PHP、C++)能够与这个服务对话,而当手动重写/维护这些语言的接口层似乎很愚蠢。 WSDL 路线会为我做到这一点。据我所知,如果 WS 需要更改,您将更新 WSDL,重新生成客户端存根,并对使用存根的代码进行任何必要的更改(无论如何都需要这样做)。

例如 - 假设我有一个用 JAVA 编写的工具,它利用 RESTful Web 服务。我想该工具将具有用于处理某些 URL、启动请求、对响应执行某些操作、将其转换为某种数据结构(如果我愿意)等的特定代码。现在假设我也有一个 Perl 工具在做一样。现在我需要 Perl 代码来做同样的事情,在特定 URL 上发出请求以获取响应,对它们做一些事情等等。在每种情况下,因此在 C++ 和 Python 和 C# 中,代码无法共享,最终我'最终会得到一个包装类/方法,它对我隐藏了很多丑陋的东西。我宁愿在一个类上调用一个函数,该函数返回我封装在一个对象中的数据,而不必担心 URL、参数、响应等。当然,也许它在任何特定的地方都没有很多代码,但是随着时间的推移,它开始增加。将其乘以每个工具,现在当我对服务进行更改时,我必须更新每个 CRUD 操作中的 URL 以及随之而来的所有内容。我想我想,使用 WSDL 是为您完成的方面。您的代码只是与存根交互。存根做什么,谁在乎?网址、参数、响应 - 如果有任何变化,只需从 WSDL 重新生成存根。如果该过程导致您的代码中断,那就这样吧,但至少我不必更新所有处理发出请求和处理响应的细节的代码。这真的不是问题吗?也许我需要做的只是创建一个服务和几个客户端,然后看看我真正面对的是什么。

虽然我是一位经验丰富的程序员,在 JAVA、Perl、Python、C++ 等方面有经验,但这是我第一次考虑编写 WS 并且之前没有使用其他 WS 的经验,所以我'我正在寻找一些指导。我是否只是使用 WSDL/SOAP 而忘记了每个人都在说 REST 是多么流行、简单和有用?

【问题讨论】:

  • 顺便说一句,使用 REST,您不必担心服务的发展,因为 REST 引起的解耦量确保客户端不会中断。因此,您无需担心客户端更新。您只需通过添加必要的功能逐步将它们带到新版本。一月
  • @JamesG 同意这种思维方式。 stackoverflow.com/a/32744753/794606

标签: java python perl rest soap


【解决方案1】:

这里没有代码生成问题。

REST 很少需要任何类型的代码生成。它只是带有简单 JSON(或 XML)有效负载的 HTTP 请求。

您使用现有的 HTTP 库(例如 Apache Commons 或 Python urrlib2)。您使用现有的 JSON(或 XML)库。 (例如,Jersey 项目有一个很好的 JAXB-JSON 转换)。

什么是“生成”?我们用 Java 和 Python 编写的 RESTful 库几乎相同,只是通过 HTTP 库发出 REST 请求。

class OurService {
    def getAResource( String argValue ) {
        path = { "fixed", argValue };
        URI uri= build_path( path );
        return connection.get( uri )

[我省略了异常处理。]

您是否尝试在复杂的 SOAP 接口/实现分离中分层?


一个“用 JAVA 编写,利用 RESTful Web 服务”的客户端......一个“做同样事情的 Perl 工具”......“在 C++ 和 Python 和 C# 中”。

正确。

“无法共享代码”

正确。代码不能共享。您必须用适当的语言编写每个客户端。编写某种“生成器”来从 WSDL 创建此代码是 (1) 大量工作和 (2) 不必要的。每种语言都有用于发出 REST 请求的独特语法和独特的库。但它是如此简单和通用,几乎没有任何东西。

Python 中的典型例子是

class Some_REST_Stub( object ):
    def get_some_resource( self, arg ): # This name is from the WSDL
        uri = "http://host:port/path/to/resource/%s/" % arg # This path is from the WSDL
        data= urllib2.open( uri )
        return json.load( data )

此代码块比描述它所需的 WSDL 短。而且更改似乎更容易,因为名称是方法名称,而 URI 只是一个字符串。

在大多数语言中,客户端大致就是这么简单。我刚刚用 Java 写了一堆 REST 客户端代码。它更冗长,但它是通用的东西。构建一个请求,解析返回的 JSON。就是这样。

RESTful WSDL 声明将两条微不足道的信息隐藏在大量 XML 中。

  • 它为 URI 提供了一个“接口名称”。

  • 它通过提供 Stub 类方法名称来记录 GET、PUT、POST 和 DELETE 的含义。

它不会帮助您编写太多代码,因为没有太多代码。请注意,所有 REST 请求都具有相同的通用 HttpRequest 和 HttpResponse 结构。该请求包含通用实体。响应还包含一个必须解析的通用实体。 REST 很少——关键是要尽可能简单。

它在很大程度上消除了对 WSDL 的需求,因为一切都是通用的 JSONObject 或 XML URLEncoded 并作为字符串发送。

“我宁愿在一个类上调用一个函数,该函数返回封装在一个对象中的数据,而不必担心 URL、参数、响应等。”

正确,您必须编写一个“存根”类。它几乎没有代码,而且会比描述它所需的 WSDL 短。

“将其与每个工具相乘,现在当我对服务进行更改时,我必须更新每个 CRUD 操作中的 URL 以及随之而来的所有事情。”

您可以为每个客户端更新每种语言的存根类。或者您可以更新 WSDL,然后重新生成每个客户端。看起来工作量是一样的,因为 URI 被简单地封装在客户端代码中。

“我想我想,使用 WSDL 就是为您完成的方面。”

我不清楚“完成”了什么。将冗长而复杂的 WSDL 转换为简单的存根类?我想这可能会有所帮助。除了 WSDL 比存根类大。我建议您可能会发现简单地编写存根类更容易。它比 WSDL 短。

“您的代码只是与存根交互。”

正确。

“存根做什么,谁在乎?网址、参数、响应 - 如果有任何变化,只需从 WSDL 重新生成存根。”

遗憾的是,几乎所有这些都不需要任何真正的编程。从 WSDL 生成它比简单地编写它需要更多的工作。 URI 是一个字符串。参数是通用 JSONObjects。响应是包含 JSONArray 的通用 HttpResponse。就是这样。

“我也不必更新所有处理发出请求和处理响应细节的代码。”

除了,提出请求没有任何有趣的细节。 HTTP 是简单、通用的东西。 GET、POST、PUT 和 DELETE 几乎完全相同。

【讨论】:

  • 我想我只是没有考虑到与 REST 服务交互所需的代码是如此微不足道,以至于不需要接口层。这是你的意思吗?
  • 你认为你需要什么“接口层”? REST 请求只是 HTTP。我们将它们包装在一个代理类中——本质上——将方法名称映射到路径字符串。真的没什么。你想建什么接口层?也许您应该更新您的问题以解释您认为图层应该是什么。
  • 更新了我的意思的例子。
【解决方案2】:

化石,

我建议您不要为此费心学习 SOAP。 Ws-* 的学习曲线非常高,而且(不必要的)复杂性很可能会吞噬你。

看看您的技能组合(Java、Perl、Python、C++),您应该对 REST(或至少基于 HTTP)方法感到非常满意。并且:您会很快得到结果。

正如 S.Lott 所说,不要担心代码生成。你不需要它。

如有问题,我建议您加入 Yahoo 群组的 rest-discuss: http://tech.groups.yahoo.com/group/rest-discuss/ 您通常会在所有 REST 方面立即获得帮助。

就我个人而言,我还没有看到任何可以从使用 WS-* 中受益的用例。

一月

【讨论】:

    【解决方案3】:

    你看重的代码生成方面是一个维护项目,但我怀疑它的真正价值。

    无论是通过 WSDL 文档还是您自己的用于 REST 样式实现的语法文档,客户端都必须遵守已发布的接口。 WS/SOAP(代码生成)开发模型可能有更多工具,但我认为那是因为它很笨重,需要它们。

    对您的网络服务的“可集成性”没有影响。无论哪种情况,这都是发布正式接口(以任何形式)的问题。使用 REST 样式的服务,您从接口更改到实现更改的速度可以说更快。启动(和使用)WS-* 代码生成工具需要时间。

    【讨论】:

      【解决方案4】:

      仅供参考 - REST 确实有一个类似于 WSDL 的自动生成架构定义,称为 WADL。但几乎没有人使用它。

      【讨论】:

      • 另外,“WSDL 2.0 版可用于描述 REST Web 服务”,允许对非常简单的 REST 服务创建非常复杂的描述。
      【解决方案5】:

      Apache CXF 具有对 REST 客户端的 Java 支持,在许多情况下,为您提供与完整 SOAP 相同的“代码生成”优势。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-20
        • 1970-01-01
        相关资源
        最近更新 更多