样式的Web服务使用REST还是SOAP?

我已经实施了两项REST服务:Twitter和Netflix。 这两次,我努力寻找决定将这些服务公开为REST而不是SOAP的决定所涉及的用途和逻辑。 我希望有人能够告诉我我错过了什么,并解释为什么REST被用作这些服务的服务实现。

1)实现REST服务比实现SOAP服务花费的时间要长得多。 所有现代语言/框架/平台都有工具可以读取WSDL并输出代理类和客户端。 实现一个REST服务是通过手工完成的,并且通过阅读文档获取它。 此外,在实施这两项服务时,您必须“猜测”管道中将返回的内容,因为没有真正的模式或参考文档。

2)为什么编写一个返回XML的REST服务呢? 唯一的区别是用REST你不知道每个元素/属性代表的类型 - 你自己来实现它,并希望有一天一个字符串不会出现在你认为总是int的字段中。 SOAP使用WSDL定义了数据结构,因此这是一件不容易的事情。

3)我听说过使用SOAP的抱怨,它具有SOAP Envelope的“开销”。 在这个时代,我们真的需要担心少数几个字节吗?

4)我听说过使用REST可以将URL弹入浏览器并查看数据。 当然,如果你的REST服务使用简单认证或不认证。 例如,Netflix服务使用OAuth,在您提交请求之前,您需要对事物进行签名和编码。

5)为什么我们需要每个资源的“可读”URL? 如果我们使用工具来实现该服务,我们真的关心实际的URL吗?


煤矿里的金丝雀。

我现在一直在等待这样的问题近一年。 这一天不可避免,我相信未来几个月我们会看到更多类似的问题。

警告标志

您绝对正确,构建RESTful客户端比SOAP客户端需要更长的时间。 SOAP工具包带走了大量样板代码,并且几乎毫不费力地使客户端代理对象可用。 使用Visual Studio和服务器URL这样的工具,我可以在五分钟内在本地访问任意复杂的远程对象。

返回application / xml和application / json的服务对于客户端开发人员来说非常烦人。 我们应该如何处理这些数据?

幸运的是,许多提供REST服务的站点还提供了一堆客户端库,以便我们可以使用这些库访问一组强类型对象。 似乎有点愚蠢。 如果他们使用SOAP,我们可以自己编写代理类。

SOAP开销,哈。 这是杀死的延迟。 如果人们真的担心通过网线的超出字节数,那么HTTP可能不是正确的选择。 你看过用户代理头使用了多少字节?

是啊,你有没有试过使用网络浏览器作为除HTML和JavaScript以外的其他任何调试工具。 相信我这很糟糕。 你只能使用两个动词,高速缓存不断阻碍,错误处理吞噬了如此多的信息,它不断寻找一个该死的favicon.ico。 只要射击我。

可读网址。 只有名词,没有动词。 是的,只要我们只进行CRUD操作,并且只需要以一种方式访问​​对象层次结构,就很容易。 不幸的是,大多数应用程序需要比这更多的功能。

即将发生的灾难

目前有大量开发人员正在开发与REST服务集成的应用程序,这些服务正在与您拥有相同的结论集合。 他们承诺简单,灵活,可扩展性,可演化性和偶然重用的圣杯。 网络本身的特点,怎么会出现问题。

但是,他们发现版本控制同样有问题,但编译器无法检测问题。 随着数据结构的演变和URL的重构,手写客户端代码是一件难事。 围绕名词和四个动词设计API可能非常困难,特别是使用REST风格的Url狂热者会告诉您何时可以使用查询字符串。

开发人员会开始问我们为什么要浪费我们的努力来支持Json格式和Xml格式,为什么不把我们的努力集中在一个方面并做得好呢?

事情是如何发生这样的错误

我会告诉你哪里出了问题。 我们作为开发人员让营销部门利用我们的主要弱点。 我们对银弹的永恒追求使我们忽视了REST真正的现实。 在表面上,REST看起来非常简单。 使用Urls命名您的资源并使用GET,PUT,POST和DELETE。 地狱,我们开发人员已经知道如何做到这一点,我们一直在处理具有表和列的数据库以及具有SELECT,INSERT,UPDATE和DELETE的SQL语句。 它应该是一块蛋糕。

还有一些人讨论过REST的其他部分,比如自描述性和超媒体约束,但这些约束并不像资源标识和统一界面那么简单。 在希望的目标是简单性的情况下,似乎增加了复杂性。

这种淡化REST版本在许多方面在开发人员文化中得到验证。 服务器框架的创建鼓励了资源标识和统一接口,但没有做任何支持其他约束。 条款开始浮现围绕区分方法,(HI-REST与LO-REST,企业REST与学术REST,REST与RESTful)。

有几个人尖叫,如果你不应用所有的约束,它不是REST。 你不会得到好处。 没有一半REST。 但是这些声音被贴上了宗教狂热分子的标签,他们对他们的宝贵名词从默默无闻中被盗而成为主流感到不满。 试图让REST听起来更加困难的嫉妒的人比现在更难。

REST这个词已经成为主流。 几乎每个拥有API的主要网络媒体资源都支持“REST”。 Twitter和Netflix是两个非常高调的。 可怕的是,我只能想到一个自描述的公共API,并且有一些真正实现了超媒体约束。 确定一些网站,如StackOverflow和Gowalla支持他们的回应链接,但他们的链接有巨大的漏洞。 StackOverflow API没有根页面。 想象一下,如果网站没有主页,那么网站会如何成功!

你害怕我被误导了

如果你已经做到了这一点,那么对你的问题的简短回答是那些API(Netflix和Twitter)不符合所有的约束,因此你不会得到REST apis应该带来的好处。

REST客户端的构建时间比SOAP客户端需要更长的时间,但它们并不与一个特定的服务绑定,所以您应该能够跨服务重用它们。 以Web浏览器的经典示例为例。 网页浏览器可以访问多少项服务? Feed饲料怎么样? 现在,平均Twitter客户端可以访问多少种不同的服务? 是的,只有一个。

REST客户端不应该构建为与单个服务接口,它们应该构建为处理可由任何服务提供服务的特定媒体类型。 显而易见的问题是,如何为一个提供application / json或application / xml的服务构建一个REST客户端。 那么你不能。 这是因为这些格式对于REST客户端完全没有用处。 你自己说过,

由于没有真实的模式或参考文档,你必须对管道中会回来的东西进行“猜测”

您对Twitter等服务绝对正确。 但是,REST中的自描述性约束表明,HTTP内容类型头应该精确描述通过线路传输的内容。 提供应用程序/ json和application / xml不会告诉你有关内容。

当考虑基于REST的系统的性能时,有必要查看更大的图片。 谈论信封字节就像谈论快速排序和shell排序时的循环展开一样。 有些情况下SOAP可以更好地执行,并且有些情况下REST可以更好地执行。 上下文就是一切。

REST通过对其支持的媒体类型以及对缓存的复杂支持非常灵活,从而获得了很大的性能优势。 尽管几乎所有的约束条件都必须遵守,但缓存工作良好。

关于可读URL的最后一点是最具讽刺意味的。 如果您确实承诺了超媒体约束,那么每个URL都可能是一个GUID,客户端开发人员在可读性方面不会丢失任何内容。

URIs对客户端不透明的事实是开发REST系统时最关键的事情之一。 可读的URL对于服务器开发者来说很方便,并且结构良好的URL使得服务器框架能够更容易地分派请求,但这些实现细节不应该对使用API​​的开发者产生影响。

Twitter API甚至没有接近RESTful,这就是为什么你无法看到通过SOAP使用它的任何好处。 Netflix API距离更近,但是对通用媒体类型的使用表明,即使未能遵守单一约束,也会对服务带来的好处产生深远影响。

这可能不全是他们的错

我对服务提供商做了大量倾销,但需要两次才能以REST方式跳舞。 服务可能会在宗教上遵循所有约束条件,客户仍然可以轻松地取消所有好处。

如果客户端硬编码访问某些类型的资源,那么它会阻止服务器更改这些URL。 基于对服务如何构建其url的隐式知识的任何类型的URL构建都是违规的。

假设从链接返回哪种表示形式可能会导致问题。 根据HTTP头文件中未明确规定的知识对表示内容做出假设,肯定会造成耦合,这将导致未来的痛苦。

他们是否应该使用SOAP?

就我个人而言,我不这么认为。 REST做得正确可以让分布式系统长期发展。 如果您正在构建分布式系统,这些分布式系统的组件由不同的人开发并需要持续多年,那么REST是一个不错的选择。


SOAP是一个面向对象的 远程过程调用技术栈。 它通过在现有协议(HTTP)之上构建新的抽象来工作。

REST是一种面向文档的方法,它简单地使用现有协议(HTTP)的功能。 “REST”只是一个流行词 - 概念是这样的:只要按照它设计的方式使用网络!

回应编辑质疑:

  • “实现REST服务比实现SOAP服务花费的时间要长得多。”

    嗯,不,它不能无限延长。 而在你想要检索的东西已经是文档或文件的情况下 ,它实际上要快得多 。 例如,WMS(网络映射服务)的OGC规范定义了协议的SOAP和REST版本,几乎没有人实现SOAP版本是有原因的 - 这是因为如果你试图获取地图,它是只需构建一个URL并从该URL获取图像字节比将其封装到SOAP消息中更容易。 但是,我会同意,如果Web服务的重点是在域对象模型中传输一些强类型对象,则SOAP更适合该用途。

  • “为什么编写一个返回XML的REST服务?”

    那么,是的,那可能很愚蠢。 但这取决于XML是什么。 如果某个地方有明确定义的模式,那么就没有歧义。 例如,您可以将WSDL URL视为一种RESTful Web服务,用于检索有关Web服务的信息。 在这种情况下,增加另一个SOAP请求的开销将毫无意义。

    一般来说,当正在传输的内容可​​以被认为是一个文件时,REST就会成为一个单元 。 当内容需要被视为具有成员对象时,SOAP获胜。

  • “我听说过使用SOAP的抱怨,SOAP Envelope有”额外开销“,在这个时代,我们真的需要担心几个字节吗?”

    是。 不是在任何情况下,但有很多网站都有很大的流量,因为它有所不同。 它是否足以胜过使用SOAP而不是REST的语义差异 ? 我对此表示怀疑。 如果你正在做一个对象远程协议,并且字节数有所作为,SOAP可能不是你的工具 - 也许你应该使用CORBA或DCOM。

  • “我听说过有了REST,你可以将URL弹出到浏览器中并查看数据。”

    是的, 如果在浏览器中查看数据是有意义的 ,这是支持REST的一个重要论点。 例如,使用图像数据,这是调试服务的简单方法 - 只需将URL粘贴到浏览器的地址栏中,然后查看图像的外观即可。 或者,如果返回的数据是XML格式的,并且您有一个引用的XML样式表在浏览器中呈现为可读的HTML,那么您可以在一个包中获得语义标记和简单可视化的好处。 但是你是正确的,当使用更复杂的认证方案时,这种好处大多会消失。 如果您无法将所有身份验证信息编码到每个HTTP请求中 ,那么我会认为它根本不算作REST。

  • “为什么我们需要每个资源的”可读“URL?如果我们使用工具来实现这个服务,我们真的关心实际的URL吗?”

    这得看情况。 为什么我们需要Web上的任何资源的可读URL? 您可以阅读Tim Berners-Lee的散文Cool URIs不要改变原理,但基本上,只要资源在未来可能仍然有用,那么该资源的URI应该保持不变。

    显然,对于短暂的资源(如文章中的“今天的钱”链接),不需要它,因为如果相应资源消失,引用资源的需求就会消失。 但对于更永久的资源(例如StackOverflow问题,或IMDB上的电影),您希望拥有一个永久有效的URL。 当你设计一个Web服务时,你需要决定资源本身是否可以超越你的服务,如果是这样的话,那么REST可能是正确的选择。

  • 为了记录,是的,自NetFlix或Twitter存在之前,我一直在开发网页。 不,我还没有任何需要或有机会将客户实施到NetFlix或Twitter的服务。 但即使他们的服务非常难以合作,这并不意味着他们在其上实施服务的技术很糟糕 - 只是这两种实现是不好的。

    长话短说:REST和SOAP 只是工具 。 他们各有优点和缺点。 如果你拥有的唯一工具是锤子,那么每个问题看起来都像一个钉子。 因此,了解这两种工具并学习如何正确使用它们,然后为每项工作选择合适的工具。


    诚实的问题值得诚实的回答。 但首先,如果你不认为它是修辞性的,你为什么会用这个问题的文本作为另一个问题的答案?

    无论如何:

  • 所有现代语言/框架/平台都有工具可以读取WSDL并输出代理类和客户端。实现REST服务是通过阅读文档手动完成的。

    就像浏览器供应商已经阅读并重新阅读HTML 4.01规范来尝试实现一致的浏览体验。 您是否反映过浏览器早在互联网银行和计算器出现之前就已经发明的事实,然而,您可以使用浏览器来完成这些事情。 这是因为每个人都同意使用HTML(以及CSS,JS,JPEG等相关格式)的唯一原因。

    博客实际上并不新鲜,有人提出了AtomPub,它允许任何博客软件访问和更新博客中的帖子,就像任何网页浏览器可以访问任何网页一样。 这非常简洁,并且由于协议规定的RESTful约束而起作用。

    但对于Twitter和Netflix,目前还没有普遍认为“所有现存的微博都会使用媒体类型的应用程序/推文”,这主要是因为微博是如此新颖。 也许在几年之后,少数微博服务将落户于同一个API,这样Twitter,Facebook,Identica就可以互操作。 他们现有的API都不在RESTful附近,无论他们声称多少,所以我不认为它很快就会发生。

    此外,在实施这两项服务时,您必须”猜测“管道中会回来什么,因为没有真正的模式或参考文档。

    你击中了头部。 REST全部是关于分布式和超媒体的,这几乎总结了它。 浏览器会查看它从请求中获得的内容并将其显示给用户。 一个HTML页面通常会产生更多的GET请求,例如CSS,脚本和图像。 通常只将图像渲染到屏幕上,执行JavaScript等等。 浏览器每次都做它做的事情,因为它找到了<img><style>标记中的链接,并且响应媒体类型为image/jpegtext/css

    如果Twitter制作了一个基于超媒体的API,那么每当你关注推文链接时,它可能总是会返回一个application/tweet文,但是客户端永远不应该假设它,并且总是在进行操作之前检查它得到的内容。

  • 为什么编写一个返回XML的REST服务?

    这一切都归结为媒体类型。 与HTML一样,如果您看到一个您不知道实际含义的元素,HTML规范会指示您忽略它们,并处理标记的“主体”(如果有)。 同样,原子规范指示您忽略未知元素和外部标记(来自不同的名称空间),而不处理主体(IIRC)。

    为通用问题域设计媒体类型(如富文本问题域的HTML媒体类型)非常困难。 为非常狭窄的问题域制作媒体类型可能更容易(比如推文)。 但是,设计可扩展性并指定客户端(和服务器)在看到不符合规范的元素或数据项时应如何反应总是一个好主意。 例如,JPEG具有特定于应用程序的记录类型(例如APP1),用于包含各种元数据。

  • 我听说过使用SOAP的抱怨,SOAP Envelope有”额外开销“,在这个时代,我们真的需要担心几个字节吗?

    不,我们不。 REST绝对不是关于在线路上的有效性,它实际上是在交换线路效率.REST的效率来源于其他所有约束条件所实现的缓存的可能性:Fielding的论文指出:然而,权衡是统一的接口性能下降效率,因为信息是以标准化的形式传输的,而不是针对应用程序需求的信息。 REST接口被设计为高效用于大规模超媒体数据传输,针对Web的常见情况进行优化,但导致其他形式的架构交互不是最佳的接口。 我不认为SOAP Envelope字节计数开销是一个有效的问题。

  • 我听说过有了REST,你可以将URL弹出到浏览器中并查看数据。

    是的,这也是一个无效的论点。 它不这样工作。 即使它确实有效,那里的大多数REST API都使用浏览器不知道的媒体类型,但它仍然无法工作。

    但是,与浏览器相比,测试基于HTTP的API有更多的可能性,比如命令行实用程序或浏览器扩展,它们允许您控制HTTP请求的几乎任何方面,检查响应头并发现要遵循的链接。 但即便如此,这远不如生成WSDL存​​根并使三行程序调用该函数那么简单。

  • 为什么我们需要每个资源的”可读“URL?如果我们使用工具来实现这个服务,我们真的关心实际的URL吗?

    如果你看看网络是如何工作的,我很确定人们总是很高兴维基百科页面的URI看起来像这样, http://en.wikipedia.org/wiki/?oldid=376349090 http://en.wikipedia.org/wiki/Stack_overflow而不是http://en.wikipedia.org/wiki/?oldid=376349090 。 但它对REST实际上并不重要。 尝试做对的重要事情是选择将相关数据放在不太可能改变的URI中。 您可能认为数据库ID永远不会改变,但是当两个数据集需要合并时会发生什么? 您的所有主键都会更改。 页面标题(Stack_overflow)不会更改。

  • 对不起,很长的回应,但我相信这个问题是有效的,并没有在此之前解决SO。 我相信达雷尔米勒在他回来时也会回答他的答案。

    编辑:格式

    链接地址: http://www.djcxy.com/p/12347.html

    上一篇: style web service use REST or SOAP?

    下一篇: Main differences between SOAP and RESTful web services in java