放置与后置 - REST

时间:2010-09-07 03:15:31

标签: http rest crud

在查看“petclinic”中的代码时,Spring 3.0示例的一部分我注意到以下几行

<c:choose>
  <c:when test="${owner.new}"><c:set var="method" value="post"/></c:when>
  <c:otherwise><c:set var="method" value="put"/></c:otherwise>
</c:choose>

SO的讨论中,似乎PUT应该用于“创建/更新”,POST用于“更新”。

哪个是对的?

使用post为“create”和put为“update”有什么影响?

注意:根据HTTP / 1.1规范。在引用的SO讨论中引用,上面给出的代码似乎具有正确的行为。

2 个答案:

答案 0 :(得分:12)

根据HTTP规范,POST和PUT都有明确定义的行为。

POST请求的结果应该是从属于请求URL的新资源;响应应包含Location头,其中包含新创建的资源的URL。

PUT的结果应该是请求URL处的资源更新。如果请求URL中没有现有资源,则可以创建新资源。

由于POST也与表单一起用作传递表单数据的机制,因此产生了混淆。表单的最常见实现是回发到表单页面所在的相同URL,从而错误地认为POST操作用于更新。但是,在此特定用法中,表单页面不是资源。

考虑到所有这些,这是正确的(当然我认为:-))用法:

POST应该用于在以下情况下创建新资源:
  - 新资源从属于现有资源   - 创建时未知资源标识/ URL

PUT应该用于使用众所周知的URL更新现有资源。它也可用于在知名URL上创建资源;但是,它有助于以不同的方式考虑这种情况 - 如果在发出PUT请求之前知道资源URL,则可以将其视为已存在但位于空的此位置的资源相同。

答案 1 :(得分:6)

这很简单:

  • POST允许任何事情发生,并且不限于创建“从属”资源,而是允许客户端“向数据提供数据块...” - 处理过程“(RFC 2616 sec 9.5)。 POST表示“这是您刚才要求的数据”
  • PUT用作GET 的反面。通常的流程是你GET一个资源,以某种方式修改它,然后你把它放回到你得到的相同的URI。 PUT表示“请将此文件存储在此URI”。

PUT(用于存储文件)的一致性允许中间人(例如缓存)使他们可能在该确切URI处拥有的任何缓存响应无效(因为他们知道它是即将改变)。 PUT的一致性还允许客户(理解这一点)通过首先检索资源(GET)然后发送修改后的副本来修改资源({{1} })。由于PUT的幂等性,它还允许客户重试网络故障

附注:使用PUT创建资源是可疑的。尽管在规范中是可能的,但我认为这不是一个好主意,就像使用POST执行搜索一样不是一个好主意,就像在HTTP上隧道化SOAP不是一个好主意一样。 AtomPub明确指出PUT isn't used to create atom entries

PUT普遍存在这样一个事实:HTML定义POST元素导致POST <form>实体,收件人可以随意做任何事情,包括

  • 创建从属资源(repsonse通常伴有application/x-www-form-urlencoded响应和201标题)
  • 创建完全不同的资源(通常还是Location响应和201标题)
  • 创建许多从属和/或不相关的资源(可能带有指示所创建资源的URI的简单响应)
  • 除了返回响应之外什么都不做(例如Location200)(应该使用GET的情况)
  • 修改接收POST本身的资源(返回或重定向回更新的资源)。
  • 删除一个或多个资源。
  • 上述任意组合。

唯一知道在302请求中会发生什么的人是发起请求的用户(通过点击巨大的“我确认删除我的Facebook个人资料”按钮)和处理请求的服务器。对于世界其他地方,请求是不透明的,并不意味着“此URI正在传递某些数据”。

因此,您的问题的答案是POSTPOST都可用于创建和更新。

  1. POST通常用于创建资源(如AtomPub 9.2
  2. PUT语义非常适合修改资源(如AtomPub 9.3
  3. POST可用于修改资源(如www表单编辑您的个人资料)
  4. PUT在技术上可用于创建资源(尽管我建议反对)