浅谈RESTful中的PUT,POST,PATCH

RESTful中更推荐使用HTTP的请求谓词(动词)来作为动作标识。包括GET,PORT,PUT,PATCH,DELETE。

在RESTful中文文档中有这么一句胡,“patch方法用来更新局部资源”,我们该如何理解?

先来解释一下古老的POST和PUT。

在HTTP原本的定义中[RFC2616],用于上传数据的方法只有POST和PUT。

这俩个都是更新资源,但是有本质上的区别,那就是语义。在HTTP中,PUT被定义为幂等(idempotent)的方法,POST则不是,这是一个很重要的区别。先通俗解释一下幂等,它是一个数学词语,是对于单个输入或者无输入的运算方法,如果每次都是同样的结果,则称其是幂等的。也就是说,如果一个网络重复执行多次,产生的效果是一样的,那就是幂等(idempotent)。

POST

用于提交请求,可以更新或者创建资源,是非幂等的,举个例子:最常用的就是
在用户注册功能上,每次提交都是创建一个用户账号,这个时候就用POST。 
ESTful URL地址应为:/user/creation?user_name=......&pwd=......


PUT

用于向指定URL传送更新资源,是幂等的。 
比如修改用户密码,虽然提交的还是账户名跟用户密码这个俩个必填参数,但是每次提交都只是更新该用户密码,每次请求都只是覆盖原先的值。 
ESTful URL地址应为:/user/{user_id}/modify?pwd=**


用PUT还是POST
当需要以更新的形式来修改某一具体资源的时候,如何判断用PUT还是POST呢? 
很简单,如果该更新对应的URI多次调用的结果一致,则PUT。如果每次提交相同的内容,最终结果不一致的时候,用POST,因为她不是幂等的,若反复执行多次对应的每一次都会创建一个新资源。如果请求超时,则需要验证一些:资源是否已经在服务端创建了?能否再重试一次或检查资源列表?(自己可以设置)而对于幂等方法不存在这一个问题,我们可以放心地多次请求。。

后来鉴于POST和PUT语义和功能上的不足,又加入了PATCH方法[RFC5789]。POST与PUT方法的差异是显而易见的,而PUT与PATCH方法就比较相似,但它们的用法却完全不同。

PUT方法和PATCH方法所请求的目标地址都是直接指向资源的,而POST方法请求的目标是一个行为处理器,这点很容易区分。但PUT和PATCH呢?根据规范中所介绍的PUT用于替换资源,而PATCH用于更新部分资源。这个描述其实不太好理解,但是我们可以从结构属性反向理解,那便是PATCH是非幂等的。POST方法非幂等可以理解,因为它请求服务器执行一个动作,多次发起请求可能导致动作多次执行(一直创建账号)。
而像PATCH这样请求的目标是一个资源的,它只是更新一个资源,不执行其它动作,那么不幂等的属性是什么呢?这里需要注意的,PATCH方法和POST方法有个很相似的地方,它们的实体部分都是结构化的数据。POST方法的实体结构一般是 multipart/form-data 或 application/x-www-form-urlencoded 而PATCH方法的实体结构则随其它规范定义。这和PUT方法的无结构实体相比就是最大的区别,PUT方法的实体无结构的,它直接把实体部分的数据替换到服务器的资源上。
#下面这段话很重要!
而PATCH提供的实体则需要根据程序或其它协议的定义,解析后在服务器上执行,以此来修改服务器上的数据。也就是说,PATCH请求是会执行某个程序的,如果重复提交,程序可能执行多次,对服务器上的资源就可能造成额外的影响,这就可以解释它为什么是不幂等的了。

假设我们有一个存放用户信息的数据库UserInfo,里面有userId, Name, Password,Address等多字段。可你的编辑功能因为需求,在某个特别的页面里只能修改password和address,这时候的更新怎么做?

人们通常(为徒省事)把一个包含了修改后userName的完整userInfo对象传给后端。这种做法是正确的,但是我们忽略了一点,这样会占用更多带宽。(当然大部分情况下总资源还是很小很小的)。

于是patch诞生,它可以只传部分的字段更新到数据库,表示该请求是一个局部更新,后端仅更新接收到的字段。

而put虽然也是更新资源,但要求前端提供的一定是一个完整的资源对象,理论上说,如果你用了put,但却没有提供完整的UserInfo,那么缺了的那些字段应该被清空,虽然实际上并不会,但是确实占用了更多的带宽,这里就术语sql语句优化的部分, 所以既然知道了这点就记下来吧。

restful只是标准,标准的意思是如果在大家都依此行事的话,沟通成本会很低,开发效率就高,但并非强制,所以你说在你的程序里把方法名从put改成patch没有任何影响,当然也许未来慢慢成为一个不成文的规定,或者是判断水平的标准,那是自然,因为你的后端程序并没有按照标准对两个方法做不同处理,她的表现自然是一样的。

简单说一下幂等(idempotent)。其实我也不是专业的,大概参考了很多资料

PUT 是幂等的,而 PATCH 不是幂等的。
幂等是一个数学和计算机学概念,在计算机范畴内表示一个操作执行任意次对系统的影响跟一次是相同。

在HTTP/1.1规范中幂等性的定义是:
Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request.
从定义上看,HTTP方法的幂等性是指一次和多次请求某一个资源应该具有同样的副作用。幂等性属于语义范畴,正如编译器只能帮助检查语法错误一样,HTTP规范也没有办法通过消息格式等语法手段来定义它,这可能是它不太受到重视的原因之一。但实际上,幂等性是分布式系统设计中十分重要的概念,而HTTP的分布式本质也决定了它在HTTP中具有重要地位。
基于HTTP协议的Web API是时下最为流行的一种分布式服务提供方式。无论是在大型互联网应用还是企业级架构中,我们都见到了越来越多的SOA或RESTful的Web API。为什么Web API如此流行呢?我认为很大程度上应归功于简单有效的HTTP协议。HTTP协议是一种分布式的面向资源的网络应用层协议,无论是服务器端提供Web服务,还是客户端消费Web服务都非常简单。再加上浏览器、Javascript、AJAX、JSON以及HTML5等技术和工具的发展,互联网应用架构设计表现出了从传统的PHP、JSP、ASP.NET等服务器端动态网页向Web API + RIA(富互联网应用)过渡的趋势。Web API专注于提供业务服务,RIA专注于用户界面和交互设计,从此两个领域的分工更加明晰。在这种趋势下,Web API设计将成为服务器端程序员的必修课。然而,正如简单的Java语言并不意味着高质量的Java程序,简单的HTTP协议也不意味着高质量的Web API。要想设计出高质量的Web API,还需要深入理解分布式系统及HTTP协议的特性。

参考:http://www.cnblogs.com/weidagang2046/archive/2011/06/04/idempotence.html

另外本文是参考了许多博客,我先前把所以内容整合在文档中然后整理的,以及加上自己的理解,所以有些参考来源已经不知道了,如果有冲突请联系我~~感谢!!

发布了14 篇原创文章 · 获赞 12 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Watson_Ashin/article/details/83054428