S3 REST API 和 POST 方法

我使用的是 AWS S3 REST API,并解决了一些恼人的问题后,签署它似乎工作。但是,当我使用正确的 REST 谓词来创建资源时,即 POST,我得到的是 405 method not allowed。同样的请求可以很好地使用方法 PUT并创建资源。

是我做错了什么,还是 AWS S3 REST API 不完全符合 REST?

77779 次浏览

是的,将 CRUD 映射到 HTTP 方法是错误的。

尽管常见的用法和广泛的误解,包括 Stack Overflow 上的高评价答案,POST 并不是“创建资源的正确方法”。其他方法的语义由 HTTP 协议决定,但 POST 的语义由目标媒体类型本身决定。POST 是用于任何没有被 HTTP 标准化的操作的方法,因此它可以用于创建,也可以用于更新,或者其他方法没有完成的任何操作。例如,使用 POST 进行检索是错误的,因为已经为此标准化了 GET,但是当客户机由于某种原因不能使用 PUT 时,可以使用 POST 来创建资源。

同样,PUT 也不是“更新资源的正确方法”。PUT 是完全替换资源而忽略其当前状态的方法。如果您有服务器期望的完整表示,您可以使用 PUT 进行创建; 如果您提供了完整的表示,包括您不会更改的部分,则可以使用 PUT 进行更新,但是使用 PUT 进行部分更新是不正确的,因为您要求服务器考虑资源的当前状态。PATCH 是这样做的方法。

在非正式语言中,每种方法对服务器说的是:

  • POST : 按照您为资源媒体类型记录的规则,获取此数据并将其应用到由给定 URI 标识的资源。

  • PUT : 用这个数据替换给定 URI 标识的内容,忽略已经存在的内容。

  • PATCH : 如果给定 URI 标识的资源仍然具有与上次查看时相同的状态,则对其应用这个 diff。

注意,这里没有提到 create 或 update,它们也不是这些方法语义的一部分。可以使用 POST 和 PUT 创建,但不能使用 PATCH,因为它取决于当前状态。你可以用它们中的任何一个进行更新,但是对于 PATCH,你有一个条件更新到你想要更新的状态,对于 PUT,你通过替换整个实体进行更新,所以这是一个幂等操作,对于 POST,你要求服务器根据预定义的规则进行更新。

顺便说一句,我不知道说一个 API 是否符合 REST 是否有意义,因为 REST 是一个体系结构 风格,而不是一个规范或标准,但即使考虑到这一点,只有极少数声称是 REST 的 API 是真正的 RESTful,在大多数情况下,因为他们不是 超文本驱动。AWS S3肯定不是 RESTful 的,尽管它与您的问题有关,但是它们对 HTTP 方法的使用大多数时候遵循 HTTP 标准。

原始的 HTTP 规范中,POST 请求的有效负载中给出的资源“被认为从属于指定的对象”(即请求 URL)。TimBL 之前说过(找不到参考文献) ,它是以 NNTP 中同名的方法为模型的。

添加到@Nicholos

来自 http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html

帖子:

发送的实体从属于 URI,其方式与 文件从属于包含该文件的目录,则新闻文章从属于包含该文件的目录 从属于发布它的新闻组或记录 从属于数据库

POST 方法执行的操作可能不会导致资源 在这种情况下,可以是200(OK)或204 (无内容)是否为适当的响应状态,这取决于 响应是否包括描述结果的实体

如果在原始服务器上创建了资源,则响应 应该是201(创建)

输入:

PUT 方法请求将封闭的实体存储在 提供的请求 URI。如果请求 URI 引用一个已经存在的 资源,封闭的实体应被视为一个修改 版本的一个驻留在原始服务器。如果请求-URI 不指向现有资源,而该 URI 能够 被请求用户代理定义为新资源时, 源服务器可以使用该 URI 创建资源。如果一个新资源 创建后,原始服务器必须通过201通知用户代理 (已创建)响应。如果修改了现有资源,则 200(确定)或204(无内容)应发送响应代码,以表明 成功完成申请

IMO PUT 可用于创建或修改/替换封闭实体。

+--------------------------------------+---------------------+
|                 POST                 |         PUT         |
+--------------------------------------+---------------------+
| Neither safe nor idempotent Ex: x++; | Idempotent Ex: x=1; |
+--------------------------------------+---------------------+