经常会混淆HTTP的POST/PUT方法,因为这两个方法似乎都可以用来创建或更新一个资源。
区别是细微但清楚的:
POST 方法
- 用来创建一个子资源,如 /api/users,会在users下面创建一个user,如users/1;
- POST方法不是幂等的,多次执行,将导致多条相同的用户被创建(users/1,users/2 ...
- 而这些用户除了自增长id外有着相同的数据,除非你的系统实现了额外的数据唯一性检查)
PUT 方法
- PUT比較正确的定义是 Replace (Create or Update),
- 例如 PUT /items/1 的意思是替换 /items/1 ,如果已经存在就替换,沒有就新增;
- 因此,PUT方法一般会用来更新一个已知资源,除非在创建前,你完全知道自己要创建的对象的URI
http post put 区别
**在HTTP中,PUT被定义为idempotent的方法,POST则不是,这是一个很重要的区别
举个栗子:
- POST /api/articles
- PUT /gists/:id/stars
- 如果产生两个**资源**,就说明这个服务不是idempotent(幂等的),因为多次使用产生了副作用;
- 如果后一个请求把第一个请求**覆盖**掉了,那这个服务就是idempotent的。
- 前一种情况,应该使用POST方法;
- 后一种情况,应该使用PUT方法。
PATCH 方法
- PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行**局部更新**
- HTTP PATCH method require a feature to do partial resource modification.
- The existing HTTP PUT method only allows a complete replacement of a document.
需要注意的地方
- **语义** 而非 风格;是语义的问题,换句话说:
- 也就是这取决于这个REST服务的行为是否是idempotent(幂等的)
- // 但是这个只是在语义上,同时不要太苛求语义
- DELETE 刪除,無論如何 资源 最後都将不复存在
- // PUT 替換(新增或完整更新)
- // PATCH 部分更新
Examples from github api v3
- create a gist
- POST /gists
- star a gist
- PUT /gists/:id/stars
设计 restful api 需要注意的问题
**名词复数**
URIs
names > verbs : 推荐使用具象化的名词而不是动词
plural > singular
- Resource collections: /v1/users
- Resource instances: /v1/users/007
注: idempotent 幂等的
如果一个方法重复执行多次,产生的效果是一样的,那就是idempotent的;
idempotent的意思是如果相同的操作再執行第二遍第三遍,结果还是一样的。
so :
人们通常(为徒省事)把一个包含了修改后userName
的完整userInfo
对象传给后端,做完整更新。但仔细想想,这种做法感觉有点二,而且真心浪费带宽(纯技术上讲,你不关心带宽那是你土豪)。
于是patch
诞生,只传一个userName
到指定资源去,表示该请求是一个局部更新,后端仅更新接收到的字段。
而put
虽然也是更新资源,但要求前端提供的一定是一个完整的资源对象,理论上说,如果你用了put
,但却没有提供完整的UserInfo
,那么缺了的那些字段应该被清空