HTTP PUT与POST区别

HTTP PUT与POST区别

HTTP 中的 PUTPOST 方法的区别在于,PUT 方法是幂等的:调用一次与连续调用多次是等价的(即没有副作用),而连续调用多次 POST 方法可能会有副作用,比如将一个订单重复提交多次。

HTTP PUT与POST使用说明

我们都知道,PUT 和 POST 是 HTTP 的两个方法(Method),都可以用来向 HTTP 服务器提交数据。似乎用哪个都可以,但其实两者还是有本质的区别的。首先直接摘出 RFC7231 中的的部分关键原文:

The fundamental difference between the POST and PUT methods is highlighted by the different intent for the enclosed representation. The target resource in a POST request is intended to handle the enclosed representation according to the resource’s own semantics, whereas the enclosed representation in a PUT request is defined as replacing the state of the target resource. Hence, the intent of PUT is idempotent and visible to intermediaries, even though the exact effect is only known by the origin server.

Proper interpretation of a PUT request presumes that the user agent knows which target resource is desired. A service that selects a proper URI on behalf of the client, after receiving a state-changing request, SHOULD be implemented using the POST method rather than PUT.

上面这两段描述的关键词就是 “idempotent”(幂等),理解了这个词就理解了二者的本质区别。下面就围绕这个词从以下几个角度分析 PUT 和 POST 的区别。

  1. 使用 PUT 时,必须明确知道要操作的对象,例如:

    PUT /customer/doc/1 { "name": "John Doe" }

    上面的 PUT 请求明确是对编号为 1 的文档进行操作,这里编号为 1 的文档就是要操作的对象。如果该文档不存在,就创建该文档;如果文档已经存在,就直接整个替换文档内容。

  2. 有人可能会质疑,上面的例子用 POST 也可以实现。没错,如果用将上例中的 PUT 接口改成 POST 接口,就是这样:

    POST /customer/doc/ { "name": "John Doe" }

    注意这里有一个重要的不同,这里 POST 请求并不知道要操作的对象,它只是向 HTTP 服务器提交一篇新文档,由 HTTP 服务器为该文档产生一个编号。这就是上面从 RFC7231 中摘出的第二段文字所描述的含义。

  3. 有人可能会继续质问:用 POST 也可以用来修改目标资源对象阿。说得还是没错。还是沿用上面的例子,稍作如下改动:

    POST /customer/doc/1 { "description": "I am a student" }

    这里的含义是给编号为 1 的文档增加一个属性 “description”。注意这里有两个不同:(1)这里编号为 1 的文档必须是已经存在的文档,否则必须使用 PUT;(2)这里是对目标对象的部分修改。只是增加了一个新属性 “description”,之前的属性 “name” 不受影响。

  4. 最后简要总结一下,使用 PUT 时,必须明确知道要操作的对象,如果对象不存在,创建对象;如果对象存在,则全部替换目标对象。同样 POST 既可以创建对象,也可以修改对象。但用 POST 创建对象时,之前并不知道要操作的对象,由 HTTP 服务器为新创建的对象生成一个唯一的 URI;使用 POST 修改已存在的对象时,一般只是修改目标对象的部分内容。

经过了以上 4 条的分析之后,对 PUT 和 POST 的区别应该很清楚了吧?再强调一遍,PUT 是 “idempotent”(幂等),意味着相同的 PUT 请求不管执行多少次,结果都是一样的。但 POST 则不是。就类似于 “x=1” 这条语句是幂等的,因为无论执行多少次,变量 x 的值都是 1;但 “x++” 就不是幂等的,因为每执行一次,变量 x 的值都不一样。

当然,这里讲的都是规范,都是最佳实践(best practise)。如果你在实际开发中,不按这个来,没有人能管得了你;但是当你的 REST API 要开放给别人使用时,就会和大家所接受的 “普世价值” 违背,很可能就会发生各种问题。

用PUT还是POST

当需要以更新的形式来修改某一具体资源的时候,如何判断用 PUT 还是 POST 呢?

很简单,如果该更新对应的 URI 多次调用的结果一致,则 PUT。如果每次提交相同的内容,最终结果不一致的时候,用 POST。

HTTP PUT请求区别总结

HTTP 中的 PUT 与 POST 方法的区别在于,PUT 方法是幂等的:调用一次与连续调用多次是等价的(即没有副作用),而连续调用多次 POST 方法可能会有副作用,比如将一个订单重复提交多次。