使用 HTTP GET、PUT、DELETE、POST、HEAD 的实际好处是什么?为什么不关注他们的行为优势(安全性和幂等性),忘记他们的名字,并根据我们想要的行为使用 GET、PUT 或 POST?
为什么我们不应该只使用 GET、PUT 和 POST(以及删除 HEAD、DELETE)?
使用 HTTP GET、PUT、DELETE、POST、HEAD 的实际好处是什么?为什么不关注他们的行为优势(安全性和幂等性),忘记他们的名字,并根据我们想要的行为使用 GET、PUT 或 POST?
为什么我们不应该只使用 GET、PUT 和 POST(以及删除 HEAD、DELETE)?
[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 案例中。
POST不保证安全性或幂等性。这就是PUT和DELETE的一个原因——PUT 和 DELETE 都是幂等的(即 1+N 个相同的请求与仅 1 个请求具有相同的最终结果)。
PUT用于在给定的 URI 处设置资源的状态。当您向特定 URI 上的资源发送POST请求时,该资源 不应被内容替换。最多,它应该被附加到。这就是为什么 POST 不是幂等的——在附加 POSTS 的情况下,每个请求都会添加到资源中(例如,每次都向讨论论坛发布一条新消息)。
DELETE用于确保从服务器中删除给定 URI 的资源。除了提交删除请求的情况外,通常不应使用POST进行删除。同样,在这种情况下您将发布到的资源的 URI 不应是您要删除的资源的 URI。您发布到的任何资源都是接受发布数据以附加到自身、添加到集合或以其他方式处理的资源。
如果您只关心 GET 请求的标头并且您不想在实际内容上浪费带宽,则使用HEAD 。这是很好的。
为什么我们需要的不仅仅是 POST?它允许数据双向流动,那么为什么需要 GET 呢?答案与您的问题基本相同。通过标准化各种方法的基本期望,其他流程可以更好地知道该做什么。
例如,干预缓存代理可以有更好的机会做正确的事情。
以 HEAD 为例。如果代理服务器知道 HEAD 的含义,那么它可以处理先前 GET 请求的结果,为 HEAD 请求提供正确的答案。并且它可以知道 POST、PUT 和 DELETE 不应该被缓存。
没有人发布我正在寻找的那种答案,所以我将尝试自己总结要点。
“RESTful Web Services”第 8 章“重载 POST”部分写道:“如果你想完全不使用 PUT 和 DELETE,那么通过 GET 公开对资源的安全操作以及通过重载 POST 公开所有其他操作完全是 RESTful。这样做违反了我的面向资源的架构,但它符合限制较少的 REST 规则。”
简而言之,将 PUT/DELETE 替换为 POST 会使 API 更难阅读,并且 PUT/DELETE 调用不再是幂等的。
一句话:
幂等性
再多说几句:
GET = 安全 + 幂等
PUT = 幂等
删除 = 幂等
POST = 既不安全也不幂等
“幂等”只是意味着你可以一遍又一遍地做它,它总是会做完全相同的事情。
您可以根据需要多次重新发出 PUT(更新)或 DELETE 请求,并且每次都会产生相同的效果,但是所需的效果会修改资源,因此它不被视为“安全”。
POST 请求应该为每个请求创建一个新资源,这意味着每次的效果都会不同。因此 POST 不被认为是安全的或幂等的。
像 GET 和 HEAD 这样的方法只是读取操作,因此被认为是“安全的”以及幂等的。
这实际上是一个非常重要的概念,因为它提供了一种标准/一致的方式来解释 HTTP 事务;这在安全环境中特别有用。
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
限制歧义,这将允许更好/更轻松地重用我们的简单 REST api。
你可以只使用 GET 和 POST,但是你会失去 PUT 和 DELETE 带来的一些精确性和清晰度。POST 是一个通配符操作,它可能意味着任何东西。PUT 和 DELETE 的行为非常明确。如果您想到资源管理 API,那么 GET、PUT 和 DELETE 可能涵盖了所需功能的 80%-90%。如果您将自己限制为 GET 和 POST,那么 40%-60% 的 api 是使用指定不当的 POST 访问的。
使用 GET 和 POST 的 Web 应用程序允许用户创建、查看、修改和删除他们的数据,但这样做是在最初为这些目的创建的 HTTP 命令之上的一层。REST 背后的想法之一是回归 Web 设计的初衷,即每个 CRUD 动词都有特定的 HTTP 操作。
此外,HEAD 命令可用于改善(可能很大)文件下载的用户体验。您调用 HEAD 以了解响应的大小,然后调用 GET 以实际检索内容。
有关说明性示例,请参见以下链接。它还提出了一种使用 OPTIONS http 方法的方法,此处尚未讨论。
有像 WebDAV 这样的 http 扩展需要额外的功能。
早期的网络服务器战争可能是造成它的原因。
在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 更严格的要求,以确保其功能的可靠实现。
GET、PUT、DELETE 和 POST 是一个时代的遗留物,当时大二学生认为网页可以简化为一些简单的原则。
如今,大多数网页都是复合实体,其中包含部分或全部这些原始操作。例如,一个页面可能包含用于查看或更新客户信息的表单,这些表单可能跨越多个表。
我通常在 php 中使用 $_REQUEST[],并不真正关心信息是如何到达的。我会选择使用基于效率的 GET 或 PUT 方法,而不是底层(多个)范例。