Netflix或Twitter样式的Web服务是否应使用REST或SOAP?[关闭]


145

我已经实现了两种REST服务:Twitter和Netflix。两次,我都在努力寻找将这些服务公开为REST而不是SOAP的决策所涉及的用途和逻辑。我希望有人能帮助我了解我所缺少的内容,并解释为什么将REST用作此类服务的服务实现。

  1. 实施REST服务比实施SOAP服务花费的时间无限长。存在用于所有现代语言/框架/平台的工具,这些工具可以在WSDL中读取并输出代理类和客户端。REST服务的实现是手工完成的,并且可以通过阅读文档来实现。此外,在实现这两项服务时,您必须“猜测”由于没有真正的架构或参考文档,管道中将返回的内容。

  2. 为什么要编写仍然返回XML的REST服务?唯一的区别是,使用REST时,您不知道每个元素/属性代表的类型-您可以自己实现它,并希望有一天不会在您认为永远是int的字段中遇到字符串。SOAP使用WSDL定义数据结构,因此这是理所当然的。

  3. 我听说过有人抱怨说,使用SOAP可能会使SOAP信封变得“花钱”。在当今时代,我们真的需要担心几个字节吗?

  4. 我听到过这样的论点:使用REST,您可以将URL弹出浏览器并查看数据。当然,如果您的REST服务使用的是简单身份验证或不使用身份验证。例如,Netflix服务使用OAuth,它要求您对事物进行签名和编码,然后才能提交请求。

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


5
您应该注意,REST并不是“发明”的,它自HTTP以来就存在。
德克·沃尔玛

5
您与Roy Fielding之间的对话非常有趣。:)
Gert Grenander 2010年

1
一些让我们开始的事情。首先,仇恨是一个强有力的词。第二,我们的行业充满了不止一种做事方式。因此,我不会讨论REST 的存在的哲学观点。作为一名优秀的开发人员,您应该开放使用最能解决问题的技术。对于某些Web服务,可能是REST。我写了更多,但这已经关闭了;)
Jason McCreary 2010年

1
@乔:点。但是,具有讽刺意味的是,REST不是一项“新”技术,它只是90年代初以来一直有效的新术语。@ jsm11482:这就是为什么这个问题被封闭为“主观和争论”的原因-因为它吸引了争论!
丹尼尔·普里登

2
我对这个问题的回答在这里bit.ly/cAdYAr
Darrel Miller

Answers:


193

煤矿中的金丝雀。

我已经等了差不多一年了。不可避免的是这一天将会到来,我相信在接下来的几个月中我们还会看到更多类似的问题。

警告标志

您是完全正确的,构建RESTful客户端要比SOAP客户端花费更多的时间。SOAP工具箱删除了许多样板代码,几乎不用费劲就可以使客户端代理对象可用。使用Visual Studio之类的工具和服务器URL,我可以在五分钟内在本地访问任意复杂程度的远程对象。

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

幸运的是,许多提供REST服务的站点还提供了一堆客户端库,因此我们可以使用这些库来访问一堆强类型对象。虽然似乎有点愚蠢。如果他们使用SOAP,我们可以自己对这些代理类进行代码生成。

SOAP开销,哈。延迟是致命的。如果人们真的担心通过网络传输的多余字节数,那么HTTP可能不是正确的选择。您是否看到用户代理标头使用了多少字节?

是的,您是否尝试过将Web浏览器用作除HTML和JavaScript之外的任何其他工具的调试工具。相信我,这很烂。您只能使用其中两个动词,缓存一直在妨碍您,错误处理吞噬了太多信息,它一直在寻找一个该死的favicon.ico。射死我

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

即将来临的灾难

当前有大量开发人员在开发与REST服务集成的应用程序,他们正在得出与您相同的结论。它们被承诺具有简单性,灵活性,可伸缩性,可演化性以及偶然性重用的圣杯。网络本身的特征,怎么会出错。

但是,他们发现版本控制同样是一个问题,但是编译器无法帮助发现问题。随着数据结构的发展和URL的重构,手写的客户端代码很难维护。仅围绕名词和四个动词来设计API确实非常困难,尤其是在RESTful 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 API应该带来的好处。

REST客户端的确比SOAP客户端花费更长的时间,但是它们并不局限于一种特定的服务,因此您应该能够跨服务重用它们。以网络浏览器为例。Web浏览器可以访问多少服务?资讯提供阅读器呢?现在,普通的Twitter客户端可以访问多少种不同的服务?是的,只有一个。

不应将REST客户端构建为与单个服务接口,而应构建为处理任何服务可以服务的特定媒体类型。显而易见的问题是,如何为交付application / json或application / xml的服务构建REST客户端。好吧,你不能。那是因为这些格式对REST客户端完全没有用。你自己说的

您必须“猜测”管道中将返回的内容,因为没有真正的架构或参考文档

您绝对正确使用Twitter之类的服务。但是,REST中的自描述约束表明HTTP内容类型标头应准确描述通过网络传输的内容。交付application / json和application / xml不会告诉您有关内容的任何信息。

在考虑基于REST的系统的性能时,有必要从更大的角度考虑。谈论信封字节就像谈论快速排序与外壳排序时的循环展开一样。在某些情况下,SOAP可以执行得更好,在某些情况下,REST可以执行得更好。上下文就是一切。

REST通过非常灵活地支持它所支持的媒体类型以及对缓存的复杂支持而获得了很多性能优势。为了使缓存正常工作,尽管必须遵守几乎所有限制。

到目前为止,关于可读URL的最后一点是最具有讽刺意味的。如果您真正致力于超媒体约束,那么每个URL都可以是GUID,并且客户端开发人员将不会损失任何可读性。

在开发REST系统时,URI对客户端应该是不透明的这一事实是最关键的事情之一。可读的URL对服务器开发人员来说很方便,而结构良好的URL使服务器框架更容易调度请求,但是这些是实现细节,对使用API​​的开发人员没有影响。

Twitter API甚至还不是接近REST风格的,这就是为什么您看不到通过SOAP使用它的任何好处的原因。Netflix API更加接近,但它对通用媒体类型的使用表明,即使仅遵循一个约束条件,也可能对服务所产生的收益产生深远影响。

可能不是他们的错

我已经在服务提供者上进行了大量转储,但是需要两个来完成REST跳舞。服务可能会严格遵循所有约束条件,客户仍然可以轻松撤消所有收益。

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

假设将从链接返回哪种表示形式会导致问题。基于未在HTTP标头中明确说明的知识对表示的内容进行假设,肯定会造成耦合,这将在将来引起麻烦。

他们应该使用SOAP吗?

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


4
这可能并非全部正确。亚马逊的Web服务同时具有SOAP和REST接口,其使用的85%来自REST接口。尽管所有公司都对SOAP堆栈进行了大肆宣传,但这是非常有说服力的证据,表明开发人员喜欢更简单的REST方法。消息来源:oreillynet.com/pub/wlg/3005
Suraj Chandran 2012年

3
不,那仅是令人信服的证据,表明Web开发人员喜欢他们认为更简单的东西,而不是它实际上在任何长期类型或以性能为导向的方法方面都优于。事实是,针对特定工作的正确工具是所需的,而不是“我知道这个工具,因此所有工作都必须符合它”。
凯文·威廉姆斯

61

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

REST是一种面向文档的方法,仅使用现有协议(HTTP)的功能。“ REST”只是个流行词-概念是:只需按照设计的工作方式使用网络即可!

回应对问题的编辑:

  1. “实施REST服务要比实施SOAP服务花费无限长的时间。”

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

  2. “为什么要编写仍然返回XML的REST服务?”

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

    通常,将要传输的内容视为一个文件(作为一个单元)时,REST将获胜。当需要将内容视为带有成员对象时,SOAP就会胜出。

  3. “我听说过有人抱怨说使用SOAP具有SOAP信封的“开销”。在这个时代,我们真的需要担心几个字节吗?”

    是。并非在所有情况下都如此,但是有些网站的流量很大,这会有所作为。足以抵消使用SOAP而不是REST 的语义差异是否足够?我对此表示怀疑。如果您正在执行对象远程协议,并且字节数有所不同,那么SOAP可能不是适合您的工具-也许您应该使用CORBA或DCOM。

  4. “我听说过使用REST可以将URL弹出浏览器并查看数据的说法。”

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

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

    这要看情况。为什么我们需要网络上任何资源的可读URL?您可以阅读Tim Berners-Lee的文章Cool URIs Do n't Change以获得基本原理,但基本上,只要将来该资源可能仍然有用,该资源的URI就应该保持不变。

    显然,对于暂时​​性资源(如本文中的“今天的钱”链接),不需要它,因为如果相应的资源消失了,则引用资源的需求也就消失了。但是,对于更多永久性资源(例如StackOverflow问题或IMDB上的电影),您希望拥有一个可以永久使用的URL。在设计Web服务时,您需要确定资源本身是否可以超过服务寿命,如果可以,那么REST可能是正确的选择。

记录下来,是的,自从NetFlix或Twitter出现之前,我就一直在开发网页。而且,我还没有任何需要或机会来实现NetFlix或Twitter服务的客户端。但是,即使他们的服务很难使用,也不意味着他们在其之上实现服务的技术是不好的-只是这两种实现是不好的。

简而言之:REST和SOAP 只是工具。他们每个人都有优点和缺点。如果您仅有的工具是锤子,那么每个问题都像钉子。因此,您必须了解这两种工具,并学习如何正确使用它们,然后为每项工作选择合适的工具。


11
请记住,SOAP不仅限于HTTP,因此还有其他抽象。SOAP样式消息传递可用于多种协议,因此比REST具有更广泛的覆盖范围。我认为这是一个简单的事实,许多硬核REST支持者有时无法识别。REST占有一席之地,SOAP也是如此。
jrista'7

4
@jrista:好点。SOAP并不是有任何问题,就像锤子没有任何问题一样,只要您的问题确实是钉子。相比之下,这个问题似乎是在说:“我讨厌螺丝刀!为什么锤子对每个人都不够好?让我相信螺丝刀应该存在!” -在这种情况下,它的存在是出于荒谬的。
Daniel Pryden'7

2
REST是一种建筑风格。如果确实需要,可以使用SOAP进行RESTful服务。我认为REST社区针对HTTP的SOAP的主要抱怨是,SOAP认为HTTP是一种传输协议,而它是一种传输协议。
布鲁诺

@Daniel:完全同意上面的问题...一个可怕的问题,并且作为一个理想的“主观和论证”的例子,当然这再荒谬了。:PI将对SOAP做出一个区分,但是...我认为它比“锤子”更适合“瑞士军刀”的要求。; P
jrista

3
@丹尼尔·谢什(Daniel Sheesh)!并不是要冒犯任何人。这是一个诚实的询问,因为我认为REST不是适用于这些服务和类似服务的正确方法。请不要一眼就写下我的问题。我认为这是“有争议的”是可以的,因为实际上我是在提出争议。我只是要求反驳。对我来说,说REST“使用了可以正常工作的网络”,这听起来像是“回到所有Twitter和Facebook之前的那一天……”您没有提供任何信息来解释为什么REST适用于这些类型服务。关心详细吗?
Josh M.

17

一个诚实的问题值得一个诚实的答案。但是首先,如果您认为它本质上不是修辞,那么为什么要用这个问题的文本作为对另一个问题回答

无论如何:

  1. 存在用于所有现代语言/框架/平台的工具,这些工具可以在WSDL中读取并输出代理类和客户端。通过阅读文档来手工完成REST服务。

    就像浏览器供应商上下阅读并重新阅读HTML 4.01规范一样,以尝试实现一致的浏览体验。您是否考虑过这样一个事实,即浏览器是在互联网银行和stackoverflow诞生之前就发明的,但是您可以使用浏览器来完成这些事情。之所以能够这样做,是因为每个人都同意使用HTML(以及相关格式,如CSS,JS,JPEG等)的唯一原因。

    博客实际上并不是什么新事物,有人提出了AtomPub,它允许任何博客软件访问和更新博客中的帖子,就像任何网络浏览器都可以访问任何网页一样。这非常整洁,并且由于该协议施加的RESTful约束而起作用。

    但是对于Twitter和Netflix,没有普遍的共识,即“存在的所有微博客都应使用媒体类型的application / tweet”,这主要是因为微博客太新了。也许几年后,一些微博客服务将基于相同的API,以便Twitter,Facebook,Identica可以互操作。他们现有的API都没有接近RESTful的地方,但是他们声称有很多东西,因此我不希望它很快就会真正实现。

    此外,在实现这两项服务时,您必须对由于没有真正的架构或参考文档而将通过管道返回的内容进行“猜测”。

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

    如果Twitter使用基于超媒体的API,则application/tweet每次您访问推文链接时,它都可能总是返回一次,但是客户端永远不要假定它,并且在对其执行操作之前始终检查其内容。

  2. 为什么编写仍然返回XML的REST服务?

    所有这些都归结为媒体类型。与HTML一样,如果您看不到元素的真正含义,则HTML规范会指示您忽略它们,并处理标签的“ body”(如果有)。同样,atom spec指示您忽略未知元素和外部标记(来自不同名称空间),而不处理主体(IIRC)。

    为通用问题域设计媒体类型(就像在RTF问题域的HTML媒体类型中一样)非常困难。为非常狭窄的问题域创建媒体类型可能要容易得多(如鸣叫)。但是设计可扩展性并指定客户端(和服务器)在看到不符合规范的元素或数据项时应该如何反应始终是一个好主意。JPEG例如具有特定于应用程序的记录类型(例如APP1),该记录类型用于包含各种元数据。

  3. 我听说过有人抱怨说使用SOAP具有SOAP信封的“开销”。在这个时代,我们真的需要担心几个字节吗?

    不,我们不。REST绝对不是要提高线的效率,它实际上是在交换线的效率。REST的效率来自所有其他约束启用缓存的可能性: 菲尔丁的论文指出:权衡是,统一的接口会降低效率,因为信息是以标准化形式而不是特定于应用程序需求的形式传输的。REST接口被设计为对于大颗粒超媒体数据传输是高效的,针对Web的常见情况进行了优化,但是导致的接口对于其他形式的体系结构交互不是最佳的。 我认为SOAP信封字节计数开销不是一个真正的问题。

  4. 我听说过使用REST可以将URL弹出浏览器并查看数据的说法。

    是的,那也是无效的参数。那样行不通。即使它确实起作用,但大多数狭窄的 REST API都使用了浏览器不知道的媒体类型,并且仍然不起作用。

    但是,除了浏览器可以测试基于HTTP的API外,还有更多的可能性,例如命令行实用程序或浏览器扩展,它们使您可以控制HTTP请求的几乎任何方面,检查响应标头并发现供您遵循的链接。即便如此,这远比生成WSDL存​​根和编写三行程序来调用函数要容易得多。

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

    如果您查看网络的工作原理,我可以肯定,人们对于Wikipedia页面的URI看起来应该是这样http://en.wikipedia.org/wiki/Stack_overflow而不是,大体上感到高兴http://en.wikipedia.org/wiki/?oldid=376349090。但这对于REST实际上并不重要。要正确处理的重要事情是选择将相关数据放置在不太可能更改的URI中。您可能会认为数据库ID永远不会更改,但是当需要合并两个数据集时会发生什么?您的所有主键都会更改。页面标题(Stack_overflow)不会改变。

抱歉,回复很长,但我相信这个问题是正确的,因此在此之前尚未解决。我确定Darrel Miller也会在回来后添加他的答案。

编辑:格式化



3

WSDL和其他文档级协议是冗余的。除了提供文档和提交表单外,HTTP协议还支持更丰富的操作集。

REST的支持者对此冗余感到不舒服。


那并没有告诉我为什么我应该对这些类型的服务使用REST。对我来说,它只是不适合。说“ HTTP协议除了提供文档和提交表单外,还支持更丰富的操作集”,并不意味着如果存在更好的条件,我们就应该实际使用它们!
Josh M.

我的隐含观点是REST是精益的。它在协议(HTTP)级别上工作。
公元前。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.