文档结构  
翻译进度:已翻译     翻译赏金:0 元 (?)    ¥ 我要打赏

设计REST API的一个挑战就是选择正确的HTTP方法(GETPUTPOST 等)来对应执行的操作。  有些人错误地认为可以自由选择任何方法,只要客户端与服务器端一致。 这是不对的,因为一个请求可能会被基于HTTP方法类型优化的中介或中间件说优化。这些优化依赖HTTP方法的两个特点:幂等性和安全性,它们定义在 HTTP规范中.

第 1 段(可获 2 积分)

安全的HTTP方法: 安全的方法并不会造成任何副作用。这些操作是只读的,如:查询数据库。

幂等的HTTP方法: 幂等性就是保证多次执行同一个请求产生的影响是相同的。

幂等性和安全性是HTTP方法的属性,服务器应用程序必须正确实现它们。也就是说你实现了一个操作并且使用HTTP的幂等性方法调用了它,你就必须保证在相同的输入条件下多次调用这个操作时返回相同的结果。

第 2 段(可获 2 积分)

GET: 幂等而且安全

GET 请求用于信息的获取,这些请求必须是幂等而且安全的:也就是说任何使用 GET 方法执行的操作都不允许对任何资源进行修改。

GET /books

获取指定的图书

GET /books/<title>

POST: 非幂等

POST 请求不是幂等的。一般用于创建新和更新已有的资源。例如,假设我们有一个 Student 资源,包含属性:namecollegemajor 和 gpa. 为了登记一个新的学生,我们使用 POST 来创建新资源:

POST /students/ // Create a new student
{
  "name": "Michael Scarn",
  "college": "Stanford",
  "major": "computer science"
}
第 3 段(可获 2 积分)

POST 请求允许对资源进行部分更新

例如:需要更新学生 GPA 成绩, POST 请求需要更新的字段(gpa)到指定记录(student_id )

POST /students/<student_id>
{
  "gpa": "3.9"
}

以上例子中,如果 student_id 记录不存在,应用程序应该响应错误信息 HTTP 404: Not Found

PUT:幂等

(译注:在编程中 一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同)

PUT 请求可以用来创建新资源或者更新已经存在的资源。当用于更新资源时,不用于 POST请求的是 PUT 请求必须包含资源所有的属性。

同样的如 POST 案例中 要更新某学生 GPA 成绩,PUT 请求如下:

PUT /students/<student_id>
{
  "name": "Michael Scarn",
  "college": "Stanford",
  "major": "computer science",
  "gpa": "3.9"
}

 

第 4 段(可获 2 积分)

在上述例子中,如果 PUT 请求中的 student_id 不存在,应用将会创建一个新记录并赋值给 student_id。

如果你想知道为什么 PUT 请求必须包含所有的属性,而不只是你想修改的属性的话,只需要想清楚下面在 PUT 请求中的允许部分更新的假设情况即可。假设学生换专业,客户端会发起两个 PUT 请求:第一个是更新学生目前专业的的 GPA 平均成绩,第二个请求是更新专业并重置 GPA。这个 PUT 请求必须按照如下顺序发起:

PUT /students/<student_id> //Partial update: Violates idempotency contract
{
  "gpa": "3.85"
}

PUT /students/<student_id> //Partial update: Violates idempotency contract
{
  "major": "engineering",
  "gpa": "0.0"
}
第 5 段(可获 2 积分)

假设,由于网络错误导致第二个请求先于第一个请求到达。 由于客户端认为PUT请求是幂等的,所以可能重试第一个请求,这就会导致错误的修改学生新专业的GPA分数为3.85, 使得数据不一致了。这非常难于跟踪且违反了幂等性:不同状态下的多个调用结果。

PUT /students/<student_id>
{
  "name": "Michael Scarn",
  "college": "Stanford",
  "major": "engineering",
  "gpa": "3.85" // GPA updated for the wrong major!
}

修改部分属性时是非常重要的特别是数据包含多个属性。 对于修改部分属性而言十分浪费,因为你得先使用GET获取整个数据然后发送所有属性。 在现实中,很多开发人员使用了PUT来进行部分属性修改,这违反了幂等性原则。 对于修改部分属性,应该使用POST或者本文后面提到的 PATCH。

第 6 段(可获 2 积分)

对于更新来,POST 与 PUT 重要差异:是否幂等性

有一个普遍的误解,认为RESTful不应使用HTTP POST方法更新现有资源. 大家持有这种观点的人建议:使用PUT来更新,使用POST来创建新数据。这是错误的。 REST 标准并没有禁止使用POST请求来进行更新操作。 事实上,它甚至没有讨论HTTP协议的幂等性和安全保障,这不是REST标准. Roy Fielding, 说:

有些人认为,REST建议不要使用POST来更新。 查阅我的论文,其中并没有与 CRUD 或POST相关的东西。 唯一提到是关于HTTP缺乏回写缓存。 缺乏特异性的主要的原因是HTTP方法的定义是Web架构定义的一部分, 而不是REST架构风格。 例如,  RESTful不会使用GET 执行安全操作,因为它违反了HTTP协议中GET的定义, 会误导中间程序和爬虫。

第 7 段(可获 2 积分)

因此,选择PUT 和POST 的规则:这些方法是否幂等性。由于PUT是幂等的,所以当第一次请求的响应没有准时到达时客户端或中间程序可以再次执行这个PUT请求 ,即使这个请求已经被服务器端处理过了。为了保证幂等性,PUT请求必须替换整个数据,因此就必须把所有数据都发送出去。所以应该使用 POST 或PATCH (非幂等性)来进行部分修改。

DELETE: 幂等

DELETE 请求是幂等的,用于删除一个数据。 大家的一个共同困惑是:重复调用DELETE应该返回什么HTTP状态码。 有些人认为DELETE是幂等,所以它应该都返回相同的HTTP状态,如: HTTP 200。 这是错误的。 虽然在你需要它而返回相同的状态代码是没有害处的, 返回不同的状态代码如: HTTP 404: 没有找到 违反幂等性。幂等性本身并不关心返回给客户端的是什么。 它是指一些资源在服务器上的状态.,因此第一次调用delete验证成功后返回:HTTP 200: OK ,后面的请求就返回:HTTP 404: Not Found , 因为在这两种情况下, 在服务器端资源已删除、状态没变化。如果响应体为空也可以返回: HTTP 204: No Content 。

第 8 段(可获 2 积分)

PATCH: 非幂等

我喜欢把 PATCH 请求作为是 PUT 请求的非幂等版本,因为它是非幂等的,可用来执行部分更新:

PATCH /students/<student_id> //Partial update: OK
{
  "gpa": "3.85"
}

采用 PATCH 用于部分更新或者是用 POST ,这完全取决于你自己。

下表是总结:

HTTP Method幂等?操作?
GETyes数据获取或者查询
POSTNO创建或者更新资源,允许部分更新
PUTyes创建或者更新资源,不允许部分更新
DELETEyes删除资源
PATCHNO部分更新资源

文章作者 Umer Mansoor.

第 9 段(可获 2 积分)

文章评论