使用REST而不是非REST HTTP的优点是什么?
显然, REST只是关于如何使用HTTP的一套约定 。 我想知道这些公约提供了哪些优势。 有人知道吗?
我不认为你会得到一个很好的答案,部分是因为没有人真正同意REST 是什么。 维基百科页面在stream行语和解释上很重要。 讨论页面只是看看有多less人不同意这一点。 据我所知,REST意味着:
我们尝试使用URL来标识资源,然后使用HTTP操作GET
, POST
, PUT
和DELETE
来为他们做一些事情,而不是使用getter和getter的随机URL,并且对所有的getter和POST
使用GET
。 。 所以,而不是
GET /get_article?id=1 POST /delete_article id=1
你会做的
GET /articles/1/ DELETE /articles/1/
然后POST
和PUT
对应于“创build”和“更新”操作(但没有人同意)。
我认为caching参数是错误的,因为查询string通常被caching,除此之外你并不需要使用它们。 例如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/
(或者不pipe怎样,在发生这些事情之前都很难想象)!
所以总而言之,我只能看到两个优点:
- 您的networkingAPI可能更清晰,更易于理解/发现。
- 在与网站同步数据时,使用REST可能更容易,因为您可以只说
synchronize("/articles/1/")
等等。 这很大程度上取决于你的代码。
不过我觉得有一些相当大的缺点:
- 并非所有的行为都能轻松映射到CRUD(创build,读取,检索,更新,删除)。 你甚至可能不处理对象types资源。
- 这是额外的努力,可疑的好处。
- 混淆
PUT
和POST
方式。 用英语来表示类似的东西(“我要在墙上发布/发布通知”)。
所以最后,我会说:除非你真的想要额外的努力,或者如果你的服务真的很好地映射到CRUD操作,保存REST的第二个版本的API。
编辑
我刚刚发现了REST的另一个问题:在一个请求中做多个事情并不容易,或者指定要获取的复合对象的哪些部分。 这对于往返时间显着并且连接不可靠的移动站来说尤其重要。 例如,假设您正在facebook时间线上发布post。 “纯”的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”查询参数select要返回的字段(或连接)。 例如,这个URL只会返回Ben的id,name和picture: https : //graph.facebook.com/bgolub?fields= id,name,picture
我不知道如何用REST做这样的事情,如果你做了它仍然算作REST。 我肯定会忽视任何人试图告诉你,你不应该那样做(特别是如果原因是“因为它不是REST”)!
简而言之,REST意味着使用HTTP的方式。
看看Roy Fielding关于REST的论文 。 我认为每个正在进行networking开发的人都应该阅读它。
请注意,Roy Fielding也是HTTP协议背后的关键驱动力之一。
为了说明一些优点:
- 简单。
- 您可以充分利用HTTPcaching和代理服务器来帮助您处理高负载。
- 它可以帮助您组织一个非常复杂的应用程序到简单的资源中
- 即使您没有专门为他们devise(可能是因为他们不在您创build应用程序时),新客户端也很容易使用您的应用程序。
简单地说: 无 。
随意downvote,但我仍然认为没有非REST HTTP的真正好处。 目前所有的答案是无效的。 目前投票最多的答案是:
- 简单。
- 您可以充分利用HTTPcaching和代理服务器来帮助您处理高负载。
- 它可以帮助你组织一个非常复杂的应用程序到简单的资源中
- 即使您没有专门为他们devise(可能是因为他们不在您创build应用程序时),新客户端也很容易使用您的应用程序。
简单
使用REST,您需要为您的服务器端脚本和客户端脚本提供额外的通信层=>实际上比使用非REST HTTP更复杂。
2.caching
caching可以由服务器发送的HTTP头来控制。 REST不添加任何在非REST中缺less的function。
3.组织
REST不帮你组织一些东西。 它迫使您使用您正在使用的服务器端库支持的API。 当您使用非REST方法时,您可以以相同的方式(或更好)组织您的应用程序。 例如,请参阅模型 – 视图 – 控制器或MVC路由 。
4.易于使用/实施
根本不是真的。 这一切都取决于你如何组织和logging你的应用程序。 REST不会神奇地使你的应用程序更好。
恕我直言,REST所能实现的最大优势就是减less客户端/服务器之间的耦合。 随着时间的推移发展一个REST接口而不破坏现有的客户端要容易得多。
可发现
每个资源都具有对其他资源的引用,无论是层次结构还是链接,因此很容易浏览。 这对于开发客户的人来说是一个优势,可以避免他们经常咨询文档并提供build议。 这也意味着服务器可以单方面更改资源名称(只要客户端软件不对URL进行硬编码)。
与其他工具兼容
您可以将自己的方式卷入API的任何部分,或者使用Web浏览器来导航资源。 使debugging和testing集成更容易。
标准动词名称
允许您指定操作而不必捕捉正确的措辞。 想象一下,如果OOP getters和setter不是标准化的,而有些人使用retrieve
和define
来代替。 你将不得不记住每个单独的接入点正确的动词。 知道只有less数动词可以反击这个问题。
标准化状态
如果您GET
的资源不存在,则可以确保在RESTful API中发生404
错误。 将它与一个非RESTful API相比较,它可能会返回{error: "Not found"}
,上帝知道有多less层。 如果你需要额外的空间给另一方的开发者写消息,你总是可以使用响应的主体。
例
设想两个具有相同function的API,一个遵循REST,另一个不是。 现在想象下面这些API的客户端:
REST风格:
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有一个重大的更新,可能会或可能不会改变这些接入点。 你需要重新阅读多less文档?
-
你能预测最后一个查询的回报吗?
-
您必须修改已发布的评论(删除之前)。 你可以这样做,而不检查文档?
我build议看一下Ryan Tomayko的“我如何解释我的妻子的REST”
第三方编辑
摘自waybackmaschine的链接:
怎么样一个例子。 你是一名老师,想要pipe理学生:
- 他们在什么课程
- 他们得到什么成绩,
- 紧急联系人,
- 关于你所教书籍的信息等
如果系统是基于networking的,那么这里涉及的每个名词可能都有一个URL: student, teacher, class, book, room, etc
。 …如果每个URL都有一个机器可读的表示,那么将新工具locking到系统上将是微不足道的,因为所有这些信息都是以标准方式消耗的。 …你可以build立一个全国范围的系统,能够与每个学校系统交谈,收集考试成绩。
每个系统都会使用一个简单的HTTP GET来获取彼此的信息。 如果一个系统需要添加一些东西到另一个系统,它会使用一个HTTP POST。 如果一个系统想更新另一个系统中的某个东西,它就使用一个HTTP PUT。 剩下唯一要弄清楚的是数据应该是什么样的。
我build议每个正在寻找这个问题的答案的人都要经过这个“幻灯片” 。
我无法理解REST是什么,它为什么如此酷,它的优点和缺点,与SOAP的区别 – 但是这个幻灯片非常精彩和容易理解,所以现在比以前更清楚了。
caching。
REST还有其他更深入的好处,围绕松散耦合和超文本进化,但caching机制是您关心RESTful HTTP的主要原因。
这是在菲尔丁论文写下来的。 但是,如果你不想读很多:
- 增加的可扩展性(由于无状态,caching和分层的系统限制)
- 解耦客户端和服务器(由于无状态和统一的接口约束)
- 可重复使用的客户端(客户端可以使用常规的REST浏览器和RDF语义来决定遵循哪个链接以及如何显示结果)
- 非破坏客户端(客户端只能通过特定于应用程序的语义更改来破解,因为它们使用语义而不是某些API特定的知识)
- 给每个“资源”一个ID
- 把事情联系起来
- 使用标准方法
- 具有多个表示的资源
- 沟通无国界
使用POST和GET可以做所有事情吗? 是的,这是最好的办法吗? 没有为什么? 因为我们有标准的方法。 如果你再想一想,就可以用GET来做所有的事情,那么我们为什么还要用POST呢? 因为这个标准!
例如,今天想到一个MVC模型,你可以限制你的应用程序只响应特定types的动词,比如POST,GET,PUT和DELETE。 即使在引擎盖下,一切都被模拟到POST和GET,对于不同的动作有不同的动词吗?
在REST中发现要容易得多。 我们有WADL文档(类似于传统Web服务中的WSDL),可以帮助您向世界宣传您的服务。 您也可以使用UDDI发现。 用传统的HTTP POST和GET人们可能不知道你的消息请求和响应模式来打电话给你。
一个好处是,我们可以非顺序地处理XML文档,并从不同的来源,如InputStream对象,URL,DOM节点解组XML数据…
@Timmmm,关于你的编辑:
GET /timeline_posts // could return the N first posts, with links to fetch the next/previous N posts
这将大大减less电话的数量
而且什么都不能阻止你devise一个接受HTTP参数的服务器来表示你的客户端可能需要的字段值…
但这是一个细节。
更重要的是,您没有提到REST架构风格的巨大优势(由于服务器无状态,更好的可扩展性;由于服务器无状态,更好的可用性;更好地使用标准服务,例如caching实例,当使用REST架构风格时;由于使用统一的接口,客户端和服务器之间的耦合要低得多)等等)
至于你的评论
“并不是所有的行为都能轻易映射到CRUD(创build,读取,检索,更新,删除)。”
:RDBMS也使用CRUD方法(SELECT / INSERT / DELETE / UPDATE),并且始终有一种方法来表示和处理数据模型。
关于你的句子
“你甚至可能不处理对象types资源”
:RESTfuldevise本质上是一个简单的devise – 但这并不意味着devise它很简单。 你看到差异吗? 如果您愿意的话,您将不得不考虑应用程序将代表和处理的概念,必须做些什么,以便通过资源来表示这些概念。 但是,如果你这样做,你将会得到一个更简单和有效的devise。
查询string可以被search引擎忽略。