使用 HTTP RESTful 方法 GET/POST/等。它们是多余的吗?

Posted

技术标签:

【中文标题】使用 HTTP RESTful 方法 GET/POST/等。它们是多余的吗?【英文标题】:Use of HTTP RESTful methods GET/POST/etc. Are they superfluous? 【发布时间】:2016-11-15 02:11:06 【问题描述】:

RESTful “方法”的价值是什么(即 GET、POST、PUT、DELETE、PATCH 等)?

为什么不让每个客户端都使用带有任何/所有相关参数、标头、请求体、JSON 等的“GET”方法。等等?

在服务器端,对每个方法的响应都是自定义和独立编码的!

例如,通过 GET 而不是 POST 发出数据库查询有什么不同?

我知道 GET 用于不更改数据库(或其他任何内容?)的查询。 POST 用于进行更改的调用。

但是,据我所知,RESTful 标准并没有阻止人们编写服务器对 GET 的响应并发出一个确实会更改数据库的存储过程调用。

反之亦然……RESTful 标准不会阻止人们编写服务器对 POST 的响应并发出存储过程调用,而这确实不会改变任何事情!

我并不是说中间层 (HTTP) “RESTlike”层是必要的。显然是。

假设我错了(我可能是)。是否仍然有许多 REST 服务器违反这些协议的正确使用而遭受零影响?

以下内容并没有直接解决我的问题,而只是在它周围不舒服地跳舞,就像在死音乐会上的一个酸头石匠:

Different Models for RESTful GET and POST

RESTful - GET or POST - what to do?

GET vs POST in REST Web Service

PUT vs POST in REST

我刚刚花了大约 80 个小时尝试将 PATCH 与我的 REST 服务器通信(旧的 android Java 无法识别新的 PATCH,所以我不得不在标头中发出愚蠢的 kluge HTTP-OVERIDE-METHOD)。 POST 可以正常工作,但管理员不会让步,因为他尊重 REST。

我只是不明白为什么要为每个单独的方法而烦恼。它们似乎对幂等性没有太大影响。它们似乎只是指南。如果你“违反”了这些“准则”,他们就会给别人一个机会来指责你。 但那又怎样?这些准则不是更麻烦吗? 我只是困惑。请原谅我的帖子的生硬。

不是 REST GET/POST/等。方法是多余的?

【问题讨论】:

因为那将是 RPC,而不是 REST。 【参考方案1】:

RESTful “方法”(即 GET、POST、PUT、DELETE、PATCH 等)的价值是什么?

首先,澄清一下。这些不是 RESTful 方法;这些是 HTTP 方法。 Web 是 REST 架构风格的参考实现(大部分)。

这意味着您的问题的权威答案记录在 HTTP 规范中。

但是,据我所知,RESTful 标准并没有阻止人们编写对 GET 的服务器响应并发出确实会更改数据库的存储过程调用。

HTTP 规范将某些方法指定为safe。顺便说一下,这表示一个方法是只读的;客户端不对服务器上可能发生的任何副作用负责。

区分安全和不安全方法的目的是让自动检索过程(蜘蛛)和缓存性能优化(预取)能够正常工作,而不必担心造成伤害。

但是您是对的,HTTP 标准不会阻止您更改数据库以响应 GET 请求。事实上,它甚至特别指出了您可以选择这样做的情况:

通过在网络上选择广告发起的安全请求通常会产生向广告帐户收费的副作用。

HTTP 规范还将某些方法指定为idempotent

本规范定义的请求方法中,PUT、DELETE、安全请求方法是幂等的。

使用幂等方法的动机是什么?不可靠的网络

幂等方法的区别在于如果在客户端能够读取服务器的响应之前发生通信失败,请求可以自动重复。

请注意,这里的客户端可能不是用户代理,而是参与对话的中间组件(如反向代理)。

因此,如果我正在编写一个用户代理或组件,它需要与您的服务器通信,并且您的服务器符合 HTTP 规范中的方法定义,那么我不需要知道任何关于当方法是 GET、PUT 或 DELETE 时,您的应用程序协议知道如何正确处理丢失的消息。

另一方面,POST 不会告诉我任何信息,而且由于未确认的消息可能仍在发送给您的途中,发送重复的消息副本是危险的。

难道还有许多 REST 服务器违反这些协议的正确使用而遭受零影响吗?

绝对——记住,超媒体的参考实现是 html,而 HTML 不支持 PUT 或 DELETE。如果您想提供一个调用不安全操作的超媒体控件,同时仍符合 HTTP 和 HTML 标准,那么 POST 是您唯一的选择。

这些指南不是更麻烦吗?

真的没有?它们在可靠性方面提供了真正的价值,而且它们增加的额外复杂性非常小。

我只是不明白为什么要为每个单独的方法而烦恼。它们似乎对幂等性没有太大影响。

他们不影响它,他们交流它。

服务器已经知道它的哪些资源是idempotent receivers。需要该信息的是客户和intermediary components。 HTTP 规范使您能够免费将该信息传递给任何其他兼容的组件。

对每个请求使用最合适的方法意味着您可以将解决方案部署到商品组件的拓扑中,并且它可以正常工作

或者,您可以放弃可靠的消息传递。或者,您可以在组件中编写一堆自定义代码,以明确告诉它们您的哪些端点是幂等接收器。

POST 与 PATCH

同一首歌,不同的诗句。如果资源支持OPTIONS、GET 和PATCH,那么我可以发现执行部分更新所需的所有信息,并且可以使用与其他地方相同的商品实现来执行此操作。

使用 POST 获得相同的结果需要更多的工作。例如,您需要某种机制来与客户端沟通 POST 具有部分更新语义,以及在修补特定资源时接受哪些媒体类型。

在客户端 GET 上进行每次调用,而服务器仅通过关注请求而不是方法来兑现这种调用,我会失去什么?

允许符合标准的用户代理假定 GET 是安全。如果您在可通过 GET 访问的端点上有副作用(写入),则允许代理预取端点作为优化——即使没有人预料到,副作用也会开始触发。

如果端点不是幂等接收者,那么您必须考虑到 GET 调用可能会发生多次。

此外,允许用户代理和中间组件对caching 做出假设——您希望一直到达服务器的请求不会,因为在此过程中符合要求的组件允许服务器回复出他们自己的缓存。

为了冰蛋糕,你引入了另一个额外的风险; 未定义的行为

GET 请求消息中的有效负载没有定义的语义;在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

尽管我不确定,但我相信您来自哪里,更多的是 RPC 观点。客户端发送消息,服务器响应;只要对话中的两个参与者都对消息的语义有共同的理解,那么消息中的文本是“GET”还是“POST”还是“PATCH”有关系吗?当然不是。

当 RPC 适合您要解决的问题时,它是一个很棒的选择。

但是...

网络规模的 RPC 很难。你的团队能做到吗?您的团队能否以具有成本效益的方式交付产品?

另一方面,大规模的 HTTP 相对简单;有一个巨大的好东西生态系统,使用可扩展的架构,这些架构稳定、经过测试、易于理解且价格低廉。轮胎踢得很好。

您和您的团队几乎不需要做任何事情;为遵守 HTTP 标准进行一些阻挠,从那时起,您就可以专注于交付业务价值,同时陷入成功的深渊。

【讨论】:

>因此,如果我正在编写一个用户代理或组件,它需要与您的服务器通信,并且您的服务器符合 HTTP 规范中的方法定义,那么我不会当方法是 GET、PUT 或 DELETE 时,不需要了解有关您的应用程序协议的任何信息以知道如何正确处理丢失的消息。”如果消息“丢失”会发生什么?“丢失”是什么意思?如果我发出GET 然后在我收到响应之前关闭是“丢失”吗?然后会发生什么? 丢失意味着:我的请求没有得到回应。也许你宕机了,也许我/你的网络宕机了,也许我的消息被路由到了新视野,或者你的回复被路由了。从客户的角度来看,我无法区分“我的请求没有到达您”和“您的响应没有到达我”。如果我想确保您至少收到一次消息,我需要重新发送它,直到出现狂野的 ack。 如果 I 在收到您的回复之前关闭,那么要么它不是优先事项,要么我将在我重新启动时将回复识别为丢失。也就是说,我的持久状态将允许我重建关闭时哪些消息处于待处理状态。 所以,我认为这两个响应的意思是“REST 既不提供也不阻止任何东西”...? 不客气——很抱歉花了这么长时间才意识到这是你问的问题。

以上是关于使用 HTTP RESTful 方法 GET/POST/等。它们是多余的吗?的主要内容,如果未能解决你的问题,请参考以下文章

使用 HTTP RESTful 方法 GET/POST/等。它们是多余的吗?

AngularJS的$http服务的应用

RestFul服务介绍

RESTFul中的那些事----怎样支持RESTFul的HTTP Patch方法?

重学SpringBoot系列之RestFul接口及常用注解

使用 http 基本身份验证和 restful_authentication 插件注销