使用 REST 而不是非 REST HTTP 的优点是什么?

显然是 REST 只是一组关于如何使用 HTTP 的约定。我想知道这些会议提供了哪些优势。有人知道吗?

109470 次浏览

简单地说,REST 意味着按照它应该的方式使用 HTTP。

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

注意,Roy Fielding 也是 HTTP 协议背后的关键驱动程序之一。

列举一些优点:

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

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

我建议看看 Ryan Tomayko 的 我如何向妻子解释休息

第三方编辑

节选自 waybackmachine 链接:

举个例子吧,你是个老师,想管理学生:

  • 他们在哪个班,
  • 他们的成绩如何,
  • 紧急联络人,
  • 关于你教书的信息等等。

如果这些系统是基于网络的,那么这里可能会为每个名词提供一个 URL: student, teacher, class, book, room, etc。... 如果每个 URL 都有一个机器可读的表示,那么将新的工具绑定到系统上就很简单了,因为所有这些信息都可以以标准方式使用。你可以建立一个全国范围的系统可以和每个学校系统对话来收集考试成绩。

每个系统都将使用简单的 HTTPGET 从彼此获取信息。如果一个系统需要向另一个系统添加内容,它将使用 HTTPPOST。如果一个系统想要更新另一个系统中的某些内容,它将使用一个 HTTPPUT。剩下的唯一需要弄清楚的是数据应该是什么样子的。

恕我直言,REST 支持的最大优势是减少客户机/服务器耦合。随着时间的推移,在不破坏现有客户机的情况下演变 REST 接口要容易得多。

缓存。

REST 还有其他更深层次的好处,这些好处围绕着发展——通过松散耦合和超文本的能力,但是缓存机制是您应该关心 RESTful HTTP 的主要原因。

  • 给每个“资源”一个 ID
  • 把事情联系起来
  • 使用标准方法
  • 具有多种表示形式的资源
  • 无声无息地交流

有可能只用 POST 和 GET 做所有事情吗?是的,这是最好的方法吗?没有,怎么了?因为我们有标准的方法。如果您再考虑一下,就可以使用 GET 来完成所有工作。.那么我们为什么还要使用 POST 呢?因为标准!

例如,今天考虑的是 MVC 模型,您可以将应用程序限制为只响应特定类型的动词,如 POST、 GET、 PUT 和 DELETE。即使在引擎盖下所有的东西都被模拟为 POST 和 GET,为不同的动作使用不同的动词也没有意义吗?

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

我不认为你会得到一个很好的答案,部分原因是没有人真正同意什么 REST 维基百科页面重流行语,轻解释。这个讨论页面值得浏览一下,看看人们在这个问题上有多少不同意见。然而,就我所知,REST 的意思是:

我们没有随机命名 setter 和 getter URL,对所有 getter 使用 GET,对所有 setter 使用 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-vs-POST的事情。另外,如果愿意,还可以添加更多的动词,这样就不会被人为地绑定到 HTTP 提供的内容上。例如:

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

(或者其他什么的,很难想到例子,直到它们发生!)

因此,总而言之,我认为只有两个好处:

  1. 你的 web API 可能更简洁,更容易理解/发现。
  2. 当与网站同步数据时,使用 REST 可能更容易,因为您可以只说 synchronize("/articles/1/")或其他什么。这在很大程度上取决于您的代码。

然而,我认为有一些相当大的缺点:

  1. 并非所有操作都能轻松映射到 CRUD (创建、读取/检索、更新、删除)。您甚至可能不处理对象类型资源。
  2. 这是为了可疑的利益而付出的额外努力。
  3. 对于 PUTPOST的方向感到困惑。在英语中,它们的意思相似(“我要在墙上贴个告示”).

因此,最后我想说: 除非您真的想要付出额外的努力,或者如果您的服务真的很好地映射到 CRUD 操作,否则将 REST 保存为 API 的第二个版本。


我刚刚遇到了 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 非常棒,所以让我们看看他们是怎么做的:

默认情况下,大多数对象属性在进行查询时返回。 方法返回的字段(或连接) “ fields”查询参数。例如,此 URL 只返回 本的身份、姓名和照片: Https://graph.facebook.com/bgolub?fields=id,name,picture

我不知道如何用 REST 做这样的事情,如果你做了,它是否仍然算作 REST。我当然会忽略任何试图告诉你不应该这样做的人(特别是如果原因是“因为它不是 REST”) !

简单地说: 没有

请随意降低投票,但我仍然认为没有真正的好处超过非 REST HTTP。所有当前答案无效。来自当前投票最多的答案的观点:

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

1. 简单

对于 REST,您需要为服务器端和客户端脚本添加额外的通信层 = > ,这实际上比使用非 REST HTTP 要复杂得多。

2. 缓存

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

3. 组织

REST 不是 救命你组织事情。它 力量你使用的 API 支持的服务器端库,你正在使用。当您使用非 REST 方法时,您可以以相同的方式(或更好的方式)组织应用程序。例如,请参阅 模型-视图-控制器MVC 路由

4. 易于使用/实现

完全不是。这完全取决于您如何组织和记录您的应用程序。REST 不会神奇地让您的应用程序变得更好。

我建议大家,谁正在寻找这个问题的答案,通过 这个“幻灯片”

我不能理解 REST 是什么,为什么它如此酷,它的优点和缺点,与 SOAP 的区别——但是这个幻灯片演示是如此的精彩和容易理解,所以现在对我来说比以前更清楚了。

一个优点是,我们可以不按顺序处理 XML 文档,并从不同的源(如 InputStream 对象、 URL、 DOM 节点)解组 XML 数据... ..。

发现能力

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

与其他工具的兼容性

您可以通过 CURL 访问 API 的任何部分,或者使用 Web 浏览器导航资源。使得调试和测试集成更加容易。

标准化动词名称

允许您指定操作,而无需搜寻正确的措辞。想象一下,如果 OOP 的 getter 和 setter 没有标准化,有些人使用 retrievedefine代替。你必须记住每个接入点的正确动词。知道只有少数几个动词可以解决这个问题。

标准化状况

如果 GET资源不存在,则可以确保在 RESTful API 中获得 404错误。将它与非 RESTful API 进行对比,后者可能返回包装在天知道多少层中的 {error: "Not found"}。如果您需要额外的空间来向另一端的开发人员写消息,那么您总是可以使用响应的正文。

例子

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

宁静:

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 有一个重大更新,可能改变了这些访问点,也可能没有。有多少文件需要重新阅读?

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

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

@ 提姆,关于你的编辑:

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 设计本质上是一种简单的设计——但这并不意味着设计就是简单的。你看出区别了吗?您必须对应用程序将要表示和处理的概念进行大量的思考,如果您愿意,为了通过资源表示这些概念,应用程序必须执行哪些操作。但是,如果您这样做,您最终将得到一个更简单和高效的设计。

它被写在 菲尔丁论文上,但是如果你不想读很多的话:

  • 增加了可伸缩性(由于无状态、缓存和分层系统约束)
  • 解耦的客户端和服务器(由于无状态和统一接口约束)
    • 可重用客户端(客户端可以使用一般的 REST 浏览器和 RDF 语义来决定遵循哪个链接以及如何显示结果)
    • 非中断客户端(客户端只会因应用程序特定的语义变化而中断,因为它们使用的是语义,而不是某些 API 特定的知识)