12

使用 HTTP GET、PUT、DELETE、POST、HEAD 的实际好处是什么?为什么不关注他们的行为优势(安全性和幂等性),忘记他们的名字,并根据我们想要的行为使用 GET、PUT 或 POST?

为什么我们不应该只使用 GET、PUT 和 POST(以及删除 HEAD、DELETE)?

4

14 回答 14

22

[REST][1] 方法使用 POST、GET、PUT 和 DELETE 来实现 Web 资源的 CRUD 规则。这是一种将对象公开给 Web 上的请求的简单而整洁的方法。它是没有开销的 Web 服务。

只是为了澄清语义差异。每个操作都相当不同。关键是要有很好的 HTTP 方法,这些方法具有清晰、不同的含义。

POST 创建新对象。URI 没有密钥;它接受定义对象的消息体。SQL 插入。[编辑虽然 POST 没有密钥没有技术原因,但 REST 人员强烈建议 POST 具有与 CREATE 不同的含义,它不应该有密钥。]

GET 检索现有对象。URI可能有一个键,取决于你是在做单例 GET 还是列表 GET。SQL 选择

PUT 更新现有对象。URI 有一个密钥;它接受更新对象的消息体。SQL 更新。

DELETE 删除现有对象。URI 有一个密钥。SQL 删除。

您可以使用 POST 而不是 PUT 来更新记录吗?并非没有引入一些歧义。动词应该有明确的效果。此外,POST URI 没有键,而 PUT 必须有键。

当我发布时,我期望 201 已创建。如果我不明白,那就有问题了。同样,当我 PUT 时,我期望 200 OK。如果我不明白,那就有问题了。

我想您可能会坚持在 POST 执行 POST 或 PUT 时存在一些歧义。URI 必须不同;相关的消息也可能不同。通常,REST 人员从 SQL 中获得启发,其中 INSERT 和 UPDATE 是不同的动词。

您可以假设如果记录不存在则 UPDATE 应该插入,或者如果记录存在则更新。但是,如果 UPDATE 意味着 UPDATE 并且更新失败意味着出现问题,则更简单。对 INSERT 的秘密回退使操作变得模棱两可。

如果您没有构建 RESTful 接口,那么通常只使用 GET 和 POST 进行检索和创建/更新。当一个人在表单上单击提交时,通常存在 URI 差异或消息内容差异来区分 POST 和 PUT。但是,它不是很干净,因为您的代码必须确定您是在 POST=create 案例还是 POST=update 案例中。

于 2008-09-29T01:30:17.180 回答
13

POST不保证安全性幂等性。这就是PUTDELETE的一个原因——PUT 和 DELETE 都是幂等的(即 1+N 个相同的请求与仅 1 个请求具有相同的最终结果)。

PUT用于在给定的 URI 处设置资源的状态。当您向特定 URI 上的资源发送POST请求时,该资源 不应内容替换。最多,它应该被附加到。这就是为什么 POST 不是幂等的——在附加 POSTS 的情况下,每个请求都会添加到资源中(例如,每次都向讨论论坛发布一条新消息)

DELETE用于确保从服务器中删除给定 URI 的资源。除了提交删除请求的情况外,通常不应使用POST进行删除。同样,在这种情况下您将发布到的资源的 URI 不应是您要删除的资源的 URI。您发布到的任何资源都是接受发布数据以附加到自身、添加到集合或以其他方式处理的资源。

如果您只关心 GET 请求的标头并且您不想在实际内容上浪费带宽,则使用HEAD 。这是很好的。

于 2008-10-16T18:29:44.123 回答
5

为什么我们需要的不仅仅是 POST?它允许数据双向流动,那么为什么需要 GET 呢?答案与您的问题基本相同。通过标准化各种方法的基本期望,其他流程可以更好地知道该做什么。

例如,干预缓存代理可以有更好的机会做正确的事情。

以 HEAD 为例。如果代理服务器知道 HEAD 的含义,那么它可以处理先前 GET 请求的结果,为 HEAD 请求提供正确的答案。并且它可以知道 POST、PUT 和 DELETE 不应该被缓存。

于 2008-09-29T01:35:30.287 回答
3

没有人发布我正在寻找的那种答案,所以我将尝试自己总结要点。

“RESTful Web Services”第 8 章“重载 POST”部分写道:“如果你想完全不使用 PUT 和 DELETE,那么通过 GET 公开对资源的安全操作以及通过重载 POST 公开所有其他操作完全是 RESTful。这样做违反了我的面向资源的架构,但它符合限制较少的 REST 规则。”

简而言之,将 PUT/DELETE 替换为 POST 会使 API 更难阅读,并且 PUT/DELETE 调用不再是幂等的。

于 2008-10-16T23:50:26.190 回答
2

一句话:

幂等性

再多说几句:

GET = 安全 + 幂等

PUT = 幂等

删除 = 幂等

POST = 既不安全也不幂等

“幂等”只是意味着你可以一遍又一遍地做它,它总是会做完全相同的事情。

您可以根据需要多次重新发出 PUT(更新)或 DELETE 请求,并且每次都会产生相同的效果,但是所需的效果会修改资源,因此它不被视为“安全”。

POST 请求应该为每个请求创建一个新资源,这意味着每次的效果都会不同。因此 POST 不被认为是安全的或幂等的。

像 GET 和 HEAD 这样的方法只是读取操作,因此被认为是“安全的”以及幂等的。

这实际上是一个非常重要的概念,因为它提供了一种标准/一致的方式来解释 HTTP 事务;这在安全环境中特别有用。

于 2008-10-27T15:19:28.877 回答
1

并非所有主机都不支持 PUT、DELETE。

我问了这个问题,在一个理想的世界里,我们会有所有的动词,但是......:

RESTful Web 服务和 HTTP 动词

于 2008-09-29T02:18:39.450 回答
1

HEAD 对于确定给定服务器的时钟设置非常有用(精确到 1 秒或网络往返时间,以较大者为准)。从 Slashdot 获取 Futurama 报价也很棒:

~$ curl -I slashdot.org
HTTP/1.1 200 正常
日期:格林威治标准时间 2008 年 10 月 29 日星期三 05:35:13
服务器:Apache/1.3.41 (Unix) mod_perl/1.31-rc4
SLASH_LOG_DATA:shtml
X-Powered-By:斜线 2.005001227
X-Fry:那是小鸡秀。我更喜欢这种类型的节目:World's Blankiest Blank。
缓存控制:私有
Pragma:私人的
连接:关闭
内容类型:文本/html;字符集=iso-8859-1

对于cURL-I是执行 HEAD 请求的选项。要获取给定服务器的当前日期和时间,只需执行

curl -I $server | grep ^Date

于 2008-10-29T05:36:37.180 回答
0

限制歧义,这将允许更好/更轻松地重用我们的简单 REST api。

于 2008-09-29T02:23:12.747 回答
0

你可以只使用 GET 和 POST,但是你会失去 PUT 和 DELETE 带来的一些精确性和清晰度。POST 是一个通配符操作,它可能意味着任何东西。PUT 和 DELETE 的行为非常明确。如果您想到资源管理 API,那么 GET、PUT 和 DELETE 可能涵盖了所需功能的 80%-90%。如果您将自己限制为 GET 和 POST,那么 40%-60% 的 api 是使用指定不当的 POST 访问的。

于 2008-09-29T02:30:27.597 回答
0

使用 GET 和 POST 的 Web 应用程序允许用户创建、查看、修改和删除他们的数据,但这样做是在最初为这些目的创建的 HTTP 命令之上的一层。REST 背后的想法之一是回归 Web 设计的初衷,即每个 CRUD 动词都有特定的 HTTP 操作。

此外,HEAD 命令可用于改善(可能很大)文件下载的用户体验。您调用 HEAD 以了解响应的大小,然后调用 GET 以实际检索内容。

于 2008-10-16T17:54:44.817 回答
0

有关说明性示例,请参见以下链接。它还提出了一种使用 OPTIONS http 方法的方法,此处尚未讨论。

于 2008-10-16T18:04:57.883 回答
0

有像 WebDAV 这样的 http 扩展需要额外的功能。

http://en.wikipedia.org/wiki/WebDAV

于 2008-10-17T00:00:00.133 回答
-1

早期的网络服务器战争可能是造成它的原因。

1996 年编写的 HTTP 1.0 中,只有 GET、HEAD 和 POST。但正如您在附录 D中看到的,供应商开始添加他们自己的东西。因此,为了保持 HTTP 兼容,他们被迫在 1999 年制作了 HTTP 1.1

但是,HTTP/1.0 没有充分考虑分层代理、缓存、持久连接的需求或虚拟主机的影响。此外,自称为“HTTP/1.0”的未完全实现的应用程序激增,需要更改协议版本,以便两个通信应用程序确定彼此的真实能力。

该规范定义了称为“HTTP/1.1”的协议。该协议包括比 HTTP/1.0 更严格的要求,以确保其功能的可靠实现。

于 2008-09-29T02:40:31.787 回答
-4

GET、PUT、DELETE 和 POST 是一个时代的遗留物,当时大二学生认为网页可以简化为一些简单的原则。

如今,大多数网页都是复合实体,其中包含部分或全部这些原始操作。例如,一个页面可能包含用于查看或更新客户信息的表单,这些表单可能跨越多个表。

我通常在 php 中使用 $_REQUEST[],并不真正关心信息是如何到达的。我会选择使用基于效率的 GET 或 PUT 方法,而不是底层(多个)范例。

于 2008-10-16T18:07:59.860 回答