放置与后置 - REST

ven*_*nky 2 rest http crud

在查看"petclinic"中的代码时,我注意到以下几行

<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>
Run Code Online (Sandbox Code Playgroud)

SO的讨论中,似乎PUT应该用于"创建/更新",POST用于"更新".

哪个是对的?

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

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

Fra*_*nov 12

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

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

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

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

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

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

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

  • @Franci PUT和POST之间有更大的区别.使用PUT您发送的内容必须存储在您输入的URI中.使用POST,没有这样的约束.PUT的语义远比POST要严格得多.过去的问题是有太多人尝试在HTTP方法和CRUD之间进行映射.实际上,尝试这样做并不是一件理智的事. (3认同)
  • @Darren Miller - 很好,所以他们只是改变了它,以便'PUT`和`POST`都可用于创建新的或更新现有资源.:-)随着小差`PUT`应**存储在请求URL中的封装数据,和`POST`应**处理在请求URL中的数据和_might_返回一个位置标头,_might_或_might not_是与请求URL相同.不,那里根本不会有任何混乱...... (2认同)

mog*_*sie 6

这很简单:

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

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

附注:PUT用于创建资源是可疑的.尽管在规范中是可能的,但我认为这不是一个好主意,就像使用POST执行搜索一样不是一个好主意,就像在HTTP上隧道化SOAP不是一个好主意一样.AtomPub明确声明PUT不用于创建原子条目.

POST普遍存在的原因是HTML定义<form>了导致POST application/x-www-form-urlencoded实体的元素,接收者可以利用它来做任何事情,包括

  • 创建从属资源(repsonse通常伴随着201响应和Location标头)
  • 创建一个完全不同的资源(通常也是一个201响应和Location标题)
  • 创建许多从属和/或不相关的资源(可能只有一个简单的响应,指示所创建资源的URI)
  • 除了返回响应之外什么也不做(例如200或者302)(应该使用GET的情况)
  • 修改接收POST本身的资源(返回或重定向回更新的资源).
  • 删除一个或多个资源.
  • 以上的任何组合.

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

所以回答你的问题是,无论POSTPUT可同时用于创建和更新.

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