HTTP 兩次 DELETE 同一個資源應該返回什麼

在實踐 RESTful API 設計的時候,會碰到很多需要選擇的地方。而這些在 RFC 7230 - 7235 裏面沒有說明。例如這次要說的 DELETE 方法。

根據 RFC 7231 的說法, DELETE 是冪等的。

冪等(idempotent)是什麼?在 RFC 7231 定義冪等方法的時候,是這樣說的:
A request method is considered "idempotent" if the intended effect on the server of multiple identical requests with that method is the same as the effect for a single such request. —— RFC 7231
如果使用同一種請求方法的多個等效請求對服務器的預期影響,與一個等效請求對服務器的預期影響一樣,那麼這種請求方法被認爲是冪等的。

DELETE 冪等帶來了什麼問題?

問題是:多次使用 DELETE 方法作用於同一個資源,除了第一個成功對服務端造成影響(刪除了資源)的請求,其他請求應該返回什麼狀態碼?

針對這個問題,有兩種觀點。一種觀點認爲應該返回 404 Not Found;另一種觀點認爲應該返回 2xx 狀態碼。

第一種觀點的理由是:

不能刪除一個不存在的資源,因爲它已經不存在了。而表示資源不存在的狀態碼是 404,應該返回 404 Not Found。

第二種觀點的理由是:

客戶端刪除一個資源的意圖是使得該資源不存在或者不可用。那麼刪除一次還是多次,都會讓服務端對於該資源處於同一個狀態。無論是客戶端還是服務端,都認爲這個結果是合理的,所以應該返回成功的狀態碼。

從經驗上來看,我贊成第二種觀點。

返回 4xx 會有什麼問題?

在項目中,我們需要調用其他系統的 API 來操作資源。在某些場景下當多次調用刪除同一個資源的 API 時,第一個響應是刪除成功,但後續響應都是資源不存在的錯誤。

這個時候應該認爲執行成功還是執行失敗?

如果認爲成功,那麼應該捕獲這個異常並且不做任何處理。既然我不需要做任何處理,爲何服務端不返回成功的狀態碼呢?

如果認爲失敗,那麼應該捕獲異常並且做處理。但是要處理什麼呢?“使服務端的該資源不存在” 明明就是預期的結果,卻還要做錯誤處理。這讓人很矛盾。

服務端返回 404 暴露了對該請求的處理方式,而客戶端並不關心這個信息。客戶端只想要該資源不再存在,即使該資源從未存在過。如果執行過後,該資源確實不存在了,就達到了客戶端的目的。應該告訴客戶端成功的消息。

應該返回什麼狀態碼?

  1. 如果操作立即成功,且無需給客戶端更多的信息,則返回 204 No Content
  2. 如果操作立即成功,且需要給客戶端更多的信息,則返回 200 OK 並在響應體裏附帶信息
  3. 如果操作被接受了,但可能需要比較長的時間才能執行結束,則返回 202 Accepted

多次操作成功是否應該返回不同的成功狀態碼?

有這個考慮是因爲要識別這個刪除成功的狀態究竟是否由這一次請求所造成的。

但絕大多數情況下,並不關心這一點。所以返回同一個狀態碼就行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章