71

我正在使用AWS S3 REST API,在解决了一些令人讨厌的签名问题后,它似乎可以工作。POST但是,当我使用正确的 REST 动词来创建资源时,即405 method not allowed. 相同的请求适用于方法PUT并创建资源。

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

4

4 回答 4

252

是的,您将 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 标识的资源仍然具有我上次查看时的相同状态,则将此差异应用于它。

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

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

于 2013-11-07T18:55:06.507 回答
12
+--------------------------------------+---------------------+
|                 POST                 |         PUT         |
+--------------------------------------+---------------------+
| Neither safe nor idempotent Ex: x++; | Idempotent Ex: x=1; |
+--------------------------------------+---------------------+
于 2016-01-30T00:23:03.483 回答
4

添加到@Nicholos

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

邮政:

发布的实体从属于 URI,就像文件从属于包含它的目录一样,新闻文章从属于发布它的新闻组,或者记录从属于数据库

POST 方法执行的操作可能不会产生可由 URI 标识的资源。在这种情况下,200(正常)或 204(无内容)是适当的响应状态,具体取决于响应是否包含描述结果的实体

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

放:

PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。如果创建了新资源,源服务器必须通过 201 (Created) 响应通知用户代理。如果修改了现有资源,则应发送 200(OK)或 204(No Content)响应代码以指示请求成功完成

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

于 2014-12-19T01:05:32.563 回答
3

最初的 HTTP 规范中,POST 请求的有效载荷中给出的资源被“认为从属于指定的对象”(即请求 URL)。TimBL 之前曾说过(找不到参考资料)它是根据NNTP 中的同名方法建模的。

于 2014-10-20T13:50:41.240 回答