使用REST而非非REST HTTP有什么优势?


Answers:


162

我认为您不会对此做出很好的回答,部分原因是没人真正同意REST 什么。在维基百科页面是沉重的流行语和光的解释。讨论页面值得一看,只是看看有多少人对此有不同意见。据我所知,REST意味着:

而不是随机命名的setter和getter URL和使用的GET所有的getter和POST所有制定者,我们希望拥有的URL标识资源,然后使用HTTP动作GETPOSTPUTDELETE做的东西给他们。所以代替

GET /get_article?id=1
POST /delete_article   id=1

你会做

GET /articles/1/
DELETE /articles/1/

然后POSTPUT对应于“创建”和“更新”操作(但没人同意这种方式)。

我觉得缓存参数是错误的,因为查询字符串一般缓存,再说你不是真的需要使用它们。例如,django使这种事情变得非常简单,我不会说这是REST:

GET /get_article/1/
POST /delete_article/     id=1

甚至只将动词包含在URL中:

GET /read/article/1/
POST /delete/article/1/
POST /update/article/1/
POST /create/article/

在这种情况下,这GET意味着没有副作用,并且POST意味着会更改服务器上的数据。我想,这也许是有点更清晰,更容易,尤其是当你能避免整个PUT航班吗POST事情。另外,如果愿意,您可以添加更多动词,因此您不会被人为地束缚于HTTP所提供的功能。例如:

POST /hide/article/1/
POST /show/article/1/

(或任何其他情况,除非它们发生,否则很难想到它们!)

因此,总而言之,我只能看到两个优点:

  1. 您的Web API可能更干净,更容易理解/发现。
  2. 在与网站同步数据时,使用REST可能会更容易,因为您可以随便说synchronize("/articles/1/")什么。这在很大程度上取决于您的代码。

但是我认为有一些很大的缺点:

  1. 并非所有动作都容易映射到CRUD(创建,读取/检索,更新,删除)。您甚至可能没有处理对象类型资源。
  2. 为获得可疑的好处需要付出额外的努力。
  3. 分不清哪些方式轮PUTPOST是。在英语中,它们的含义类似(“我要在墙上张贴/张贴通知。”)。

因此,总而言之,我会说:除非您真的想付出更多努力,或者如果您的服务确实非常适合CRUD操作,请为第二版API保存REST。


我刚刚遇到了REST的另一个问题:在一个请求中做不止一件事情或指定要获取的复合对象的哪些部分并不容易。这对于往返时间可能很长且连接不可靠的移动设备尤其重要。例如,假设您正在Facebook时间线上获取帖子。“纯” REST方式将类似于

GET /timeline_posts     // Returns a list of post IDs.
GET /timeline_posts/1/  // Returns a list of message IDs in the post.
GET /timeline_posts/2/
GET /timeline_posts/3/
GET /message/10/
GET /message/11/
....

这有点荒谬。Facebook的API非常适合IMO,因此让我们看看它们的作用:

默认情况下,查询时会返回大多数对象属性。您可以使用“ fields”查询参数选择要返回的字段(或连接)。例如,此URL仅返回Ben的ID,名称和图片:https : //graph.facebook.com/bgolub?fields= id,名称,图片

我不知道您将如何使用REST进行此类操作,如果您这样做了,它是否仍会算作REST。我当然会无视任何试图告诉您您不应该这样做的人(特别是如果原因是“因为它不是REST”)!


4
POST和PUT用于每个HTTP RFC。在这种情况下,PUT意味着在特定位置创建/更新某些内容-发生的情况取决于URI是否已经存在某些东西(并且它也是幂等的),而POST则意味着您要求Web服务确定将您放置在什么位置发送-然后返回您的URI(因此仅创建)。不能真正抱怨英语,不是在完全引用计算机上的任何内容时都不能使用DELETE。我想知道如何处理您编辑中提到的问题:P
Nan L

7
在我看来,Facebook API示例看起来像REST(实际上更多,以便您的示例在URL中使用动词)。没有理由为什么查询参数不能是RESTful的,只是使用可以按层次结构排列数据的路径是一种好习惯。
贾斯汀·埃默里

5
只要您不引用它们中的资源,查询字符串就完全是RESTful的。我倾向于认为它们更像是可以调整端点行为的过滤器。
Sinaesthetic

3
-1,REST是非常特定的东西-正如Roy Fielding发明时所描述的。看到这个答案。特别是:“客户端只需要知道初始URI,然后就可以从服务器提供的选项中进行选择以进行导航或执行操作。” 。基本上,如果API的任何部分都记录了端点,例如说“给定用户ID,则可以在处获取用户信息/user/{id},那么这并不麻烦。请考虑:您的浏览器是否必须经过预编程,知道如何获取HTML来解决stackoverflow问题。页面吗?
Claudiu

1
(续...)其他人滥用该术语不会改变它的含义。不过,免责声明:我仍然只是在学习REST是什么,这就是最近为我所点击的内容。
Claudiu

47

简而言之,REST意味着按原样使用HTTP。

看看Roy Fielding关于REST的论文。我认为每个从事Web开发的人都应该阅读它。

值得注意的是,Roy Fielding也是HTTP协议背后的关键驱动因素之一。

列举一些优势:

  • 简单。
  • 您可以充分利用HTTP缓存和代理服务器来帮助您处理高负载。
  • 它可以帮助您将非常复杂的应用程序组织成简单的资源。
  • 即使您没有专门为新客户设计应用程序,它也使新客户可以轻松使用您的应用程序(可能是因为创建应用程序时他们不在身边)。

11
“简单”:为什么REST比HTTP更简单?
Dimitri C.

5
“帮助您组织”:那么,仅使用GET和POST时,组织起来会更困难?
Dimitri C.

1
“它使新客户端可以轻松使用您的应用程序”:这是关于REST与普通HTTP的关系,对吗?
Dimitri C. 2010年

23
符合REST约束绝对不是一件容易的事。有时实际上很难将复杂的业务操作压缩为四个标准动词。但是,如果做得好,最终结果可能很容易理解,但是实现目标却无济于事。
Darrel Miller

6
@Dimitri:“简单”,因为它为您提供了一个简单的框架。REST HTTP!它比SOAP(名称更简单)更简单。“帮助您组织”-这个概念并不难理解,一旦正确实施,它会使事情变得非常好。REST可以作为设计应用程序的一种方式,而不是实现细节。正如Darrel指出的那样,实施起来可能并不容易,但结果却是有益的。“它使新客户端可以轻松使用您的应用程序”-再次:REST HTTP。
埃米尔·伊凡诺夫

31

简而言之:NONE

可以随意投票,但是我仍然认为与非REST HTTP相比并没有真正的好处。当前所有答案均无效。当前投票最多的答案的论点:

  • 简单。
  • 您可以充分利用HTTP缓存和代理服务器来帮助您处理高负载。
  • 它可以帮助您将非常复杂的应用程序组织成简单的资源。
  • 即使您没有专门为新客户设计应用程序,它也使新客户可以轻松使用您的应用程序(可能是因为创建应用程序时他们不在身边)。

1.简单

使用REST,您需要服务器端和客户端脚本的附加通信层=>实际上,它比使用非REST HTTP更为复杂。

2.缓存

缓存可以由服务器发送的HTTP标头控制。REST不会添加非REST中缺少的任何功能。

3.组织

REST不能帮助您组织事物。它强制您使用所使用的服务器端库支持的API。使用非REST方法时,您可以以相同的方式(或更好)来组织应用程序。例如,请参阅Model-View-ControllerMVC路由

4.易于使用/实现

完全不对。这完全取决于您组织和记录应用程序的能力。REST不会神奇地使您的应用程序更好。


3
通常,REST API更易于缓存,因为您将数据分离到具有相同生命周期(同时创建和更新)的资源中,从而可以可靠地缓存和缓存崩溃-非REST API经常返回具有已被大量后期处理,或者是多个实体的联合体,因此更难以缓存
Scott Schulthess 2015年

2
纠正它不是相互排斥的(您可以拥有一个可缓存的非休息api),但是鼓励休息设计进行api设计,这在实践中肯定是相关的,因为它鼓励了各种最佳实践(可发现性,通用接口,可维护性,智能资源建模) )
Scott Schulthess 2015年

4
“ REST无法帮助您组织事物。它迫使您使用所使用的服务器端库支持的API。” 我不确定您的意思。在不使用额外的服务器端框架的情况下创建RESTful API是完全有可能的(并且比构造非REST API不再困难)。
Michael O.

2
“借助REST,您需要附加的通信层”-humbug,您可以使用现有的HTTP库。
索伦Boisen

1
@SørenBoisen这个答案有点老了。我可能应该对其进行更新,以反映更多当前的状态。
彼得·佩勒

23

恕我直言,REST支持的最大优势是减少客户端/服务器的耦合。随着时间的推移而发展REST接口而不破坏现有客户端要容易得多。


4
你能举个例子吗?谢谢!
JanŻankowski2014年

3
这是否取决于您的非REST API的抽象程度?
约翰尼,2015年

@johnny可能,但不太可能。选择REST约束是为了明确支持组件的独立发展。如果您找到了一种在不施加相同约束的情况下更好地做到这一点的方法,那么我相信很多人都希望听到有关它的信息。
Darrel Miller 2015年

@DarrelMiller您能否详细说明一下REST如何比非REST HTTP方法更好地减少客户端/服务器的耦合?我相信您指出了Timmmm在他/她的回答中所说的观点。请查看我在Timmmm答复下的最新评论
2002年

@emilly REST系统不依赖带外信息来处理响应。对于特定请求可能返回的结果,无需做任何假设。响应告诉您所有您需要了解的内容。这允许服务器更改其行为,客户端可以知道这些更改。
Darrel Miller

15

可发现性

每个资源在层次结构或链接中都引用了其他资源,因此很容易浏览。这对于开发客户的人员来说是一个优势,可以避免他/她不断咨询文档并提供建议。这也意味着服务器可以单方面更改资源名称(只要客户端软件不对URL进行硬编码)。

与其他工具的兼容性

您可以通过CURL进入API的任何部分,或使用网络浏览器导航资源。使调试和测试集成更加容易。

标准化动词名称

允许您指定操作而不必寻找正确的措辞。想象一下,如果OOP的getter和setter方法没有被标准化,而有人使用了retrievedefine而是使用了。您将必须记住每个访问点的正确动词。知道只有少数动词可以解决这个问题。

标准化状态

如果您GET使用的资源不存在,则可以确保404在RESTful API中出错。将其与非RESTful API进行对比,该API可能返回{error: "Not found"}包装在上帝中,知道多少层。如果您需要额外的空间来向另一侧的开发人员写消息,则可以始终使用响应的正文。

想象两个具有相同功能的API,一个遵循REST,另一个不遵循。现在想象一下那些API的以下客户端:

RESTful:

GET /products/1052/reviews
POST /products/1052/reviews       "5 stars"
DELETE /products/1052/reviews/10
GET /products/1052/reviews/10

HTTP:

GET /reviews?product_id=1052
POST /post_review?product_id=1052                  "5 stars"
POST /remove_review?product_id=1052&review_id=10
GET /reviews?product_id=1052&review=10

现在考虑以下问题:

  • 如果每个客户的第一个电话都能正常工作,那么您如何确定其余的客户也能正常工作?

  • API进行了重大更新,可能会也可能不会更改这些访问点。您需要重新阅读多少文档?

  • 您可以预测最后一个查询的返回吗?

  • 您必须编辑发布的评论(在删除之前)。您可以不检查文档就能这样做吗?


这不应该是详尽无遗的清单,仅包含非常实用的优点。
BoppreH

我称赞,这是一个非常明智的答案。
EralpB

10

我建议看看Ryan Tomayko的《我如何向我的妻子解释REST》

第三方编辑

摘录自waybackmaschine链接:

举个例子。您是一名老师,想管理学生:

  • 他们上什么课
  • 他们正在取得什么成绩,
  • 紧急联络人
  • 有关您教书的信息,等等。

如果系统是基于Web的,那么这里涉及的每个名词可能都有一个URL :student, teacher, class, book, room, etc。...如果每个URL都有一个机器可读的表示形式,那么将新工具锁定到系统上将是微不足道的,因为所有这些信息都可以以标准方式使用。...您可以建立一个全国范围的系统,该系统可以与各个学校系统进行对话以收集测试成绩。

每个系统都可以使用简单的HTTP GET相互获取信息。如果一个系统需要向另一个系统添加内容,则将使用HTTP POST。如果一个系统要更新另一个系统中的内容,则使用HTTP PUT。唯一需要弄清楚的是数据的外观。


6
妻子:这又是机器人吗?
东武

4
这是一篇不错的文章,但没有提供任何示例说明为什么对所有内容使用GET和POST会很糟糕。
Dimitri C.

9
这就是为什么我试图发现为什么更好的原因:-)
Dimitri C.

7
著作已被删除。
surfen 2014年


5

我建议正在寻找这个问题答案的每个人都要进行此“幻灯片放映”

我无法理解REST是什么,为什么它是如此的酷,它的优缺点,与SOAP的不同-但是此幻灯片如此出色且易于理解,因此对我而言,现在比以前更清楚了。


3

正在缓存。

REST还有其他更深入的好处,它们通过松散的耦合和超文本围绕着可扩展性,但是缓存机制是您应该关注RESTful HTTP的主要原因。


3
您能否举个例子,说明非REST解决方案可能会缓存什么以及为什么不进行缓存?
Dimitri C.

2
@Dimitri C .:链接Wikipedia.org/article?id=19不会被代理缓存,因为它忽略了URL中传递的参数。另一方面,链接Wikipedia.org/REST将被缓存,理解吗?
副总裁

6
如果缓存是REST的主要好处,那么我可以向您保证,我将不会花费过去两年来构建RESTful服务。
Darrel Miller

Darrel,您可能正在构建分布式分布的系统,其中松散耦合是最重要的(有兴趣知道这些系统是什么类型的系统),但是大多数人却不是-或者他们正在使用技术(例如浏览器和html),其中大部分辛苦工作都为他们完成。
麦克,2010年

1
那么,为什么不直接使用GET /get_article/19/POST /update_article如果缓存是您的关心。你仍然可以做的一切只GETPOST我相信REST表示“使用GETPOSTPUTDELETE唯一的。” 而不仅仅是“不要使用查询字符串”。所以我建议不会REST。再说一次,没人能真正同意它是什么REST 所以我将其与“ Web 2.0”放在一起。
Timmmm 2012年

3

它记录在Fielding论文中。但是,如果您不想读很多东西:

  • 可伸缩性增强(由于无状态,缓存和分层系统约束)
  • 客户端和服务器解耦(由于无状态和统一的接口约束)
    • 可重用的客户端(客户端可以使用常规的REST浏览器和RDF语义来确定要遵循的链接以及如何显示结果)
    • 不中断的客户端(客户端仅因应用程序特定的语义更改而中断,因为它们使用语义而不是某些API特定的知识)

0
  • 给每个“资源”一个ID
  • 链接在一起
  • 使用标准方法
  • 具有多种表示形式的资源
  • 无状态沟通

是否可以仅通过POST和GET完成所有操作?是的,这是最好的方法吗?没有为什么?因为我们有标准方法。如果您再想一想,仅使用GET就可以完成所有操作。那么,为什么我们还要使用POST?因为有标准!

例如,今天考虑一个MVC模型,您可以限制您的应用程序仅响应特定种类的动词,例如POST,GET,PUT和DELETE。即使在幕后都将所有内容模拟为POST和GET,对不同的动作使用不同的动词也没有道理吗?


1
“仅使用GET就可以做所有事情”:我已经在Silverlight中使用HTTP GET做过一些实验。我的结论是,GET消息的大小受到很大限制,而POST消息则可能更大(再次:在Silverlight设置中)。因此,我选择对所有内容都使用HTTP POST!:-)
Dimitri C. 2010年

两种解决方案都违反标准。通过POST进行所有操作都不好,特别是对于查询。请注意,在过去的几年中,所有以前用作GET的搜索引擎现在都可以用作GET。为什么?因为“获取”方法具有这种强大的能力……
副总裁。

0

在REST中发现要容易得多。我们拥有WADL文档(类似于传统Web服务中的WSDL),可帮助您向世界宣传您的服务。您也可以使用UDDI发现。使用传统的HTTP POST和GET,人们可能不知道您的消息请求和响应模式来呼叫您。


1
用WADL文档描述RESTful Web服务不利于REST的主要优势之一,特别是从超媒体获得的所有优势。
Thomas Eizinger

@ThomasEizinger WADL真的是一件坏事吗?当前,我们正在与另一家未在其上方提供WADL的公司合作,该公司将根据请求中包含的内容返回json对象。我认为WADL将有助于清理思路。
surfmuggle 2015年

WADL在描述HTTP API方面做得很好,因为那是它的目的。根据公司提供的服务,WADL可能是一个好主意,也可能不是一个好主意。如果该服务没有利用超媒体,而只是将一些对象序列化为JSON,则它们还应该提供有关其服务的工作方式以及期望/返回的内容的文档(WADL,Swagger等)。WADL本身一点也不坏,它并不是真正的RESTful Web服务的正确工具。
Thomas Eizinger

0

优点之一是,我们可以非顺序地处理XML文档,并从不同来源(例如InputStream对象,URL,DOM节点)解组XML数据。


0

@Timmmm,关于您的编辑:

GET /timeline_posts     // could return the N first posts, with links to fetch the next/previous N posts

这将大大减少通话次数

没有什么可以阻止您设计一个接受HTTP参数来表示客户端可能想要的字段值的服务器...

但这是一个细节。

更重要的是,您没有提到REST架构样式的巨大优势(由于服务器无状态,可伸缩性更好;由于服务器无状态,可伸缩性更好;对标准服务的更好使用,例如缓存例如,使用REST体系结构样式时;由于使用统一的接口,因此客户端和服务器之间的耦合要低得多;等等。)

至于你的话

“并非所有动作都容易映射到CRUD(创建,读取/检索,更新,删除)。”

:RDBMS也使用CRUD方法(SELECT / INSERT / DELETE / UPDATE),并且总有一种表示和作用于数据模型的方法。

关于你的句子

“您甚至可能没有处理对象类型资源”

:RESTful设计从本质上来说是一种简单的设计-但这并不意味着设计就很简单。你看得到差别吗 ?您必须对应用程序将要表示和处理的概念进行很多考虑,如果愿意,必须执行哪些操作才能通过资源表示出来。但是,如果这样做,最终将得到更简单有效的设计。


-1

搜索引擎可以忽略查询字符串。


8
使用查询字符串完全是RESTful的。
Emil Ivanov

Dimitri,某些搜索引擎会忽略动态链接。不再那么多了,但它仍然皱着眉头。如果您经营的是小型网站,则googlebot可能不会为所有网页添加索引(如果路径中带有问号)。
wisty

3
...当您提到Google时,这完全是错误的:googlewebmastercentral.blogspot.com/2008/09/…–
Boldewyn

搜索引擎不会忽略查询字符串的-1。webmasters.googleblog.com/2008/09/...
青铜人
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.