簡體   English   中英

REST、HTTP DELETE 和參數

[英]REST, HTTP DELETE and parameters

為 HTTP DELETE 請求提供參數有什么非 RESTful 的嗎?


我的場景是我正在建模“您確定要刪除它嗎?” 設想。 在某些情況下,資源狀態表明請求的刪除可能無效。 您可能可以自己想象一些需要確認刪除的場景

我們采用的解決方案是給刪除請求傳遞一個參數,表示可以繼續刪除(“?force_delete=true”)

例如

DELETE http://server/resource/id?force_delete=true

我相信它仍然很安靜,因為:

(a) DELETE 的語義沒有改變 - 用戶仍然可以發送正常的 DELETE 請求,但這可能會因 409 而失敗,並且響應正文將解釋原因。 我說可能會失敗,因為(出於不值得解釋的原因)在某些情況下沒有理由提示用戶。

(b) Roy 的論文中沒有任何內容表明它違背了 REST 的精神——為什么會這樣,因為 HTTP 只是 REST 的一種實現,所以為什么傳遞 HTTP 參數很重要


有人可以向我指出一個明確的聲明,說明這不是 RESTful 的原因嗎?

在一個相關的問題上,如果用戶沒有指定 force_delete 那么我將返回409 Conflict - 這是最合適的響應代碼嗎?


跟進

經過一些進一步的研究,我認為向 DELETE 添加參數可能會違反幾個原則。

首先是實現可能違反了“統一接口”(參見Roy 論文的第 5.1.5 節

通過添加“force_delete”,我們在已經明確定義的 DELETE 方法上添加了一個額外的約束。 這個約束只對我們有意義。

您也可以爭辯說它違反了“5.1.2 客戶端-服務器”,因為確認對話確實是一個 UI 問題,而且並非所有客戶端都希望確認刪除。

任何人的建議?

不,它不是 RESTful。 您應該將動詞 ( force_delete ) 放入 URI 的唯一原因是您是否需要在 PUT/DELETE 方法不可用的環境中重載 GET/POST 方法。 從你對 DELETE 方法的使用來看,情況並非如此。

HTTP 錯誤代碼409/Conflict應用於存在阻止 RESTful 服務執行操作的沖突的情況,但用戶仍有機會自行解決沖突。 預刪除確認(沒有真正的沖突會阻止刪除)本身不是沖突,因為沒有什么可以阻止 API 執行請求的操作。

正如亞歷克斯所說(我不知道誰對他投了反對票,他是對的),這應該在 UI 中處理,因為這樣的 RESTful 服務只處理請求,因此應該是無狀態的(即它不能依賴於通過持有確認有關請求的任何服務器端信息)。

如何在 UI 中執行此操作的兩個示例是:

  • pre-HTML5 :* 向用戶顯示一個 JS 確認對話框,只有在用戶確認后才發送請求
  • HTML5 :* 使用帶有操作 DELETE 的表單,其中表單將僅包含“確認”和“取消”按鈕(“確認”將是提交按鈕)

(*) 請注意,HTML 5 之前的版本本身不支持 PUT 和 DELETE HTTP 方法,但是大多數現代瀏覽器可以通過 AJAX 調用來執行這兩種方法。 有關跨瀏覽器支持的詳細信息,請參閱此線程


更新(基於額外的調查和討論):

服務需要存在force_delete=true標志的場景違反了 Roy Fielding 的論文中定義的統一接口 此外,根據HTTP RFC , DELETE 方法可能會在源服務器(客戶端)上被覆蓋,這意味着這不是在目標服務器(服務)上完成的。

因此,一旦服務收到 DELETE 請求,它應該處理它而無需任何額外的確認(無論服務是否實際執行操作)。

我認為這是不寧靜的。 我認為 restful 服務不應該處理強制用戶確認刪除的要求。 我會在 UI 中處理這個問題。

如果這是程序的 API,那么指定 force_delete=true 是否有意義? 如果有人正在編寫腳本來刪除此資源,您是否要強制他們指定 force_delete=true 來實際刪除該資源?

這是一個老問題,但這里有一些評論......

  1. 在 SQL 中,DELETE 命令接受一個參數“CASCADE”,它允許您指定也應該刪除依賴對象。 這是一個有意義的 DELETE 參數示例,但 'man rm' 可以提供其他參數。 這些情況如何在沒有參數的情況下在 REST/HTTP 中實現?
  2. @Jan,URL 的路徑部分標識資源似乎是一個完善的約定,而查詢字符串則沒有(至少不一定)。 例子比比皆是:獲取相同資源但格式不同,獲取資源的特定字段等。 如果我們將查詢字符串視為資源標識符的一部分,則不可能有“同一資源的不同視圖”的概念無需轉向非 RESTful 機制,例如 HTTP 內容協商(出於多種原因,這可能是不可取的)。

除了亞歷克斯的回答:

請注意,http://server/resource/id?force_delete=true 標識的資源與 http://server/resource/id 不同。 例如,刪除 /customers/?status=old 還是 /customers/ 就大不相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM