当前位置: 首页 > news >正文

PUT 还是 POST ?

创建,更新与HTTP幂等性

构建基于REST API的开发者对于何时使用HTTP PUT与POST有很大的误解与困惑。有些人认为POST 应用于创建资源,而PUT则用于更新资源。其他人则认为PUT用于创建而POST用于更改资源。这两种说法都不太确切。

通常,开发者将每个HTTP方法与CRUP操作一一对应。

CRUD HTTP
Create POST
Read GET
Update PUT
Delete DELETE

的确是这样,而且GET与DELETE对应的操作是很明确的,但论及与create和update对应的HTTP方法时要取决于幂等性。

状态统一性

状态统一性在HTTP规范中是一个很重要的概念。它规定对于执行多次相同的HTTP请求,处于服务端的资源的状态是相同的。GET,HEAD, PUT与DELETE都具有这种特性,但POST没有。

为便于说明状态统一性,我们会使用一个Account集合("/accounts"),并且为了简洁我们假设每个account资源都有三个属性:givenName, surname,和status。

假设你使用HTTP PUT方法提交了一个update请求。在请求体中,你设置了givenName和surname的值分别为"John"和"Smith"。接着你又提交了另一个HTTP PUT的请求,这次你将givenName的值设置为"Johnny"。它是幂等的么?不。为什么呢?因为在这两次请求的间隙,其他请求可能已经改变了account资源的服务端状态。例如,在这两次请求之间,status的值可能已经变成了“blocked"。我们示范的请求在重复提交时不能保证在服务端的account资源的状态是相同的。

请求:

HTTP/1.1 PUT /accounts/abcdef1234
{
      “givenName”: “John”,
      “surname”: “Smith”
}

这两次请求后可能的account状态。 (受其他请求的副作用影响):

{
      “givenName”: “John”,
      “surname”: “Smith”,
      “status”: “enabled”
}

{
      “givenName”: “John”,
      “surname”: “Smith”,
      "status”: “disabled”
}

引用Dino Chiesa所述, “PUT 意为提交一个资源——用一个不同的事物完全替代给定的URL下的所有可访问资源。” 要使用PUT请求,你必须发送所有可访问属性/值,而不仅仅是你想要改变的那些。 如果我们在发送givenName和surname时加上状态值“disabled",则本次调用是幂等的并且消除了副作用。幂等性是HTTP规范的一项基本属性,并且必须确保web的互操作性与规模。

最后,我们应该指出HTTP状态统一性只能应用于服务端状态——非客户端。例如,某一客户端成功地发送了一个服务端状态统一请求,并立即再次发送这个请求但返回了一个错误(例如可能是由于违反了服务端某种约束),对于 HTTP这仍是‘合法’的。因为这个请求没有对服务端资源状态产生影响,HTTP幂等性没有破坏。

HTTP POST vs HTTP PUT

既然已经清楚了状态统一性,在执行创建和更新操作时你应该使用哪个方法呢?以下是用于合理使用这些方法的快速参考。

创建

在不知道资源标识符时你应该使用POST来创建资源。使用POST创建资源时,返回“201 Created"状态和新建资源的位置是很好的实践,因为新建资源的位置在提交时是未知的。这可以使客户端稍后访问新创建的资源如果需要的话。

HTTP/1.1 POST /accounts
{
       …
}

响应:

201 Created
Location: https://api.stormpath.com/accounts/abcdef1234
当你允许客户端指定新建资源的资源标识符时要使用PUT。但要记住,因为PUT是幂等的,你必须要发送所有可能的值。

HTTP/1.1 PUT /accounts/abcdef1234
{
      “givenName”: “John”,
      “surname”: “Smith”,
      “status”: “enabled”
}

更新

你可以使用POST更新全部或一部分值。

HTTP/1.1 POST /accounts/abcdef1234
{
      “status”: “disabled”
}
Response 200 OK

如果你想用PUT更新某一资源,则必须要更新资源的全部属性。你必须要在PUT请求中发送所有属性值以保证幂等性。

HTTP/1.1 PUT /accounts/abcdef1234
{      //FULL RESOURCE UPDATE
      “givenName”: “J”,
      “surname”: “Smith”,
      “status”: “Enabled”
}

你也可以使用POST发送所有值,这样服务端状态与处理PUT请求的结果是一样的——这不是HTTP规范所必需的。注意幂等性与HTTP缓存服务器的缓存有较强的关联,并且POST请求通常是非缓存的。如果你对缓存的副作用感冒的话,你可以使用POST来执行全部或部分更新。

POST是目前惟一的状态不统一的方法。HTTP规范对它的定义也很宽泛,并且大体上将它定义为了一个“服务端处理指令”。这就意味着在POST请求中做任何处理都是“安全”的。

最后我们要注意HTTP规范中还没有完成的另一个称为PATCH的方法。PATCH意为用于执行部分更新时的POST的替代品。然而,因为POST已经可以处理部分更新,HTTP协会似乎没有急着批准和完成PATCH的必要了。但如果批准了,PATCH将会加入POST作为另一个状态不统一的HTTP方法。

相关文章:

  • 打印选择菜单,一键安装Web服务
  • [Share]17个免费下载电子书的网站
  • Linux下安装mantis配置指南【转】
  • hadoop 1.x环境搭建
  • axios 和 cookie 的那些事
  • ICSharpCode.TextEditor使用及扩展
  • 黑莓:公司不会放弃物理全键盘
  • UGUI射线检测
  • 把屁股擦干净 - 2017 半年记
  • 深圳前海蛇口自贸片区将打造智慧城市
  • 半导体产业要成长 物联网和汽车应用担重任
  • 设值方法和取值方法
  • Incorrect column count: expected 1, actual 5,JdbcTemplate queryForList 出错
  • Hadoop之——HBASE结合MapReduce批量导入数据
  • linux 修改服务器系统时间
  • 分享一款快速APP功能测试工具
  • Android单元测试 - 几个重要问题
  • express.js的介绍及使用
  • Fundebug计费标准解释:事件数是如何定义的?
  • Java 内存分配及垃圾回收机制初探
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • PHP 7 修改了什么呢 -- 2
  • Selenium实战教程系列(二)---元素定位
  • springMvc学习笔记(2)
  • 读懂package.json -- 依赖管理
  • 基于遗传算法的优化问题求解
  • 利用jquery编写加法运算验证码
  • 前嗅ForeSpider中数据浏览界面介绍
  • 设计模式 开闭原则
  • 深入浏览器事件循环的本质
  • 微信小程序:实现悬浮返回和分享按钮
  • 用jQuery怎么做到前后端分离
  • 怎么把视频里的音乐提取出来
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​人工智能书单(数学基础篇)
  • #、%和$符号在OGNL表达式中经常出现
  • #include
  • #Linux(make工具和makefile文件以及makefile语法)
  • #我与Java虚拟机的故事#连载02:“小蓝”陪伴的日日夜夜
  • (附源码)ssm智慧社区管理系统 毕业设计 101635
  • (附源码)计算机毕业设计ssm基于Internet快递柜管理系统
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)docker:为mysql和java jar运行环境创建同一网络,容器互联
  • (一)为什么要选择C++
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)Sublime Text3配置Lua运行环境
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .net流程开发平台的一些难点(1)
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • [].slice.call()将类数组转化为真正的数组
  • [Android View] 可绘制形状 (Shape Xml)
  • [Android实例] 保持屏幕长亮的两种方法 [转]
  • [AX]AX2012开发新特性-禁止表或者表字段