使用WSDL生成REST客户端是错误的方向吗?

时间:2010-02-22 21:37:07

标签: java python perl rest soap

我打算为内网使用创建一个相当简单的Web服务。该服务最终将成为数据库的接口,这将使我能够跟踪公司内部的各种内部工具正在做什么。我想我想要一个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是为你完成的方面。您的代码只是与存根交互。什么存根做什么,谁在乎? Urls,arguments,response - 如果有任何更改,只需从WSDL重新生成存根。如果该进程导致代码中断,那么就是这样,但至少我不必更新所有处理请求和处理响应细节的代码。这真的不是问题吗?也许我需要做的只是创建一个服务和一些客户,看看我真的反对。

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

5 个答案:

答案 0 :(得分:5)

我在这里没有遇到代码生成问题。

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接口/实现分离中进行分层?


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

正确。

“代码无法共享”

正确。代码无法共享。您必须使用适当的语言编写每个客户端。编写某种“生成器”来从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。响应是通用的HttpResponses,包括JSONArray。就是这样。

“我还没有更新所有处理请求和处理响应细节的代码。”

除此之外,没有任何有趣的具体要求。 HTTP是简单的通用东西。 GET,POST,PUT和DELETE几乎完全相同。

答案 1 :(得分:1)

Fossill,

我建议您不要为此学习SOAP。 Ws- *具有非常高的学习曲线,(不必要的)复杂性可能会让你活着。

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

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

如有疑问,我建议您加入雅虎小组的讨论: http://tech.groups.yahoo.com/group/rest-discuss/ 您通常可以立即获得REST所有内容的帮助。

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

答案 2 :(得分:1)

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

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

对您的网络服务的“可集成性”没有任何影响。在任何一种情况下,这都是发布正式界面(无论采用何种形式)的问题。使用REST风格的服务,从接口更改转变为实现更改的速度可以说更快。与WS- *代码生成工具联系(并与之抗争)需要时间。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

Apache CXF对REST客户端提供Java支持,在很多情况下,它为完整的SOAP提供了相同类型的“代码生成”优势。