我正在使用AWS S3 REST API,在解决了一些令人讨厌的签名问题后,它似乎可以工作。POST但是,当我使用正确的 REST 动词来创建资源时,即405 method not allowed. 相同的请求适用于方法PUT并创建资源。
我做错了什么,还是 AWS S3 REST API 不完全符合 REST 标准?
我正在使用AWS S3 REST API,在解决了一些令人讨厌的签名问题后,它似乎可以工作。POST但是,当我使用正确的 REST 动词来创建资源时,即405 method not allowed. 相同的请求适用于方法PUT并创建资源。
我做错了什么,还是 AWS S3 REST API 不完全符合 REST 标准?
是的,您将 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 标准。
+--------------------------------------+---------------------+
| POST | PUT |
+--------------------------------------+---------------------+
| Neither safe nor idempotent Ex: x++; | Idempotent Ex: x=1; |
+--------------------------------------+---------------------+
添加到@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 可用于创建或修改/替换封闭实体。
在最初的 HTTP 规范中,POST 请求的有效载荷中给出的资源被“认为从属于指定的对象”(即请求 URL)。TimBL 之前曾说过(找不到参考资料)它是根据NNTP 中的同名方法建模的。