协慌网

登录 贡献 社区

REST 中的 PUT 与 POST

根据 HTTP / 1.1 规范:

POST方法用于请求源服务器接受请求中包含的实体作为Request-Line Request-URI标识的资源的新下级

换句话说, POST用于创建

PUT方法请求将所包含的实体存储在提供的Request-URI 。如果Request-URI引用已经存在的资源,则封闭的实体应该被视为驻留在源服务器上的实体的修改版本。如果Request-URI没有指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。

也就是说, PUT用于创建或更新

那么,应该使用哪一个来创建资源?或者需要支持两者?

答案

总体:

PUT 和 POST 都可以用于创建。

你必须问 “你在做什么动作?” 区分你应该使用什么。我们假设您正在设计一个用于提问的 API。如果您想使用 POST,那么您可以将其添加到问题列表中。如果你想使用 PUT,你会对特定问题这样做。

两者都可以使用,所以我应该在我的 RESTful 设计中使用哪一个:

您不需要同时支持 PUT 和 POST。

使用哪种方法取决于你。但请记住使用正确的,具体取决于您在请求中引用的对象。

一些考虑:

  • 您是否明确指定了您创建的 URL 对象,还是让服务器决定?如果您为它们命名,那么使用 PUT。如果您让服务器决定然后使用 POST。
  • PUT 是幂等的,所以如果你将对象 PUT 两次,它就没有效果。这是一个很好的属性,所以我会尽可能使用 PUT。
  • 您可以使用具有相同对象 URL 的 PUT 更新或创建资源
  • 使用 POST,您可以同时有 2 个请求进行 URL 修改,并且可以更新对象的不同部分。

一个例子:

我写了以下内容作为 SO 的另一个答案的一部分

POST:

用于修改和更新资源

POST /questions/<existing_question> HTTP/1.1
Host: www.example.com/

请注意以下是一个错误:

POST /questions/<new_question> HTTP/1.1
Host: www.example.com/

如果尚未创建 URL,则在指定名称时不应使用 POST 来创建 URL。这会导致 “找不到资源” 错误,因为<new_question>尚不存在。您应该首先在服务器上输入<new_question>资源。

你可以做这样的事情来使用 POST 创建资源:

POST /questions HTTP/1.1
Host: www.example.com/

请注意,在这种情况下,未指定资源名称,将返回新对象 URL 路径。

放:

用于创建资源或覆盖它。在指定资源新 URL 时。

对于新资源:

PUT /questions/<new_question> HTTP/1.1
Host: www.example.com/

要覆盖现有资源:

PUT /questions/<existing_question> HTTP/1.1
Host: www.example.com/

你可以在网上找到断言

两者都不对。


最好是根据动作的幂等性在 PUT 和 POST 之间进行选择。

PUT意味着放置一个资源 - 用不同的东西完全替换给定 URL 上的任何可用资源。根据定义,PUT 是幂等的。你喜欢这么多次,结果是一样的。 x=5是幂等的。无论以前是否存在,您都可以投入资源(例如,创建或更新)!

POST更新资源,添加辅助资源或导致更改。 POST 不是幂等的,就像x++不是幂等的一样。


通过这个论点,PUT 用于在您知道要创建的事物的 URL 时创建。当您知道要创建的事物类别的 “工厂” 或管理员的 URL 时,可以使用 POST 创建。

所以:

POST /expense-report

要么:

PUT  /expense-report/10929
  • POST到 URL 服务器定义的 URL 上创建子资源
  • PUT到 URL 在客户端定义的 URL 处完整地创建 / 替换资源
  • PATCH到 URL 更新该客户端定义的 URL 的部分资源

PUT 和 POST 的相关规范是RFC2616§9.5ff。

POST 会创建子资源 ,因此 POST 到/items会创建一个位于/items资源下的资源。例如。 /items/1 。两次发送相同的 post 数据包将创建两个资源。

PUT用于在客户端已知URL处创建或替换资源。

因此: PUT只是 CREATE 的候选者,其中客户端在创建资源之前已经知道了 url。例如。 /blogs/nigel/entry/when_to_use_post_vs_put因为标题用作资源键

PUT替换已知 URL 上的资源(如果已存在),因此两次发送相同的请求无效。换句话说, 对 PUT 的调用是幂等的

RFC 读起来像这样:

POST 和 PUT 请求之间的根本区别体现在 Request-URI 的不同含义上。 POST 请求中的 URI 标识将处理所包含实体的资源。该资源可能是数据接受过程,某些其他协议的网关或接受注释的单独实体。相反,PUT 请求中的 URI 标识请求附带的实体 - 用户代理知道 URI 的用途,并且服务器不得尝试将请求应用于其他资源。如果服务器希望将请求应用于不同的 URI,

注意: PUT 主要用于更新资源(通过全部替换它们),但最近有使用 PATCH 更新现有资源的动作,因为 PUT 指定它替换整个资源。 RFC 5789。