2010-07-20 158 views
620

我正在用基於REST的API構建應用程序,並且已經到了爲每個請求指定狀態代碼的地步。REST驗證失敗或無效重複的HTTP狀態代碼

我應該發送什麼狀態代碼來請求失敗驗證或請求試圖在我的數據庫中添加副本?

我查看了http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html,但沒有一個看起來不錯。

發送狀態碼時是否有通常的做法?

+4

參見:http://stackoverflow.com/questions/1959947/whats-an-appropriate-http-status-code-to-return-by-a-rest-api-service-for-a- vali – deamon

+10

打開http://httpstatus.es/,右鍵單擊>> Pin選項卡:P –

回答

573

對於輸入驗證失敗:400 Bad Request +您的可選說明。這在書「RESTful Web Services」中建議。 對於雙提交:409 Conflict


更新2014年6月

曾經是RFC2616,這給使用400(錯誤請求)的有關規範,而狹義

的由於格式錯誤,服務器無法理解請求

所以它可能一直認爲這是不適宜的語義錯誤。但不再是;自2014年6月相關標準RFC 7231,它取代了以前的RFC2616,給出了更廣泛的

服務器不能或 將無法​​處理請求使用400 (Bad Request)由於一些被認爲是 客戶端錯誤

+2

是的,請求主體是語法的一部分。 – deamon

+0

是的,400錯誤的請求似乎是最接近的選項。 – alexn

+0

我會用400錯誤請求和409衝突,直到找到合適的東西。 – alexn

241
  • 失敗驗證:403禁止(「服務器理解的請求,但是拒絕執行」)。與流行的觀點相反,RFC2616並沒有說「403只是用於失敗的認證」,而是「403:我知道你想要什麼,但我不會這麼做」。該情況可能會或可能不會由於身份驗證。
  • 嘗試添加重複:409衝突(「請求不能因爲與資源的當前狀態的衝突可以完成。」)

你應該肯定會給的響應更詳細的說明標題和/或正文(例如,使用自定義標題 - X-Status-Reason: Validation failed)。

+0

「403 Forbidden」具有另一種語義。請參閱http://en.wikipedia.org/wiki/HTTP_403 – deamon

+13

@deamon:這不是*規範,即維基百科,即某人對「什麼是HTTP狀態代碼的含義」的看法;請注意,頁面essentialy說:「這是什麼Apache與403意味着什麼,這是什麼IIS意味着403」,並且它沒有任何參考官方的RFC。你似乎在重複「403意味着Apache說的任何事情」。不。實際的RFC(這是相關文檔,不是Apache的實現,不是IIS的實現,不是其他人的實現)在這裏:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html – Piskvor

+0

我知道這個規範。重點是「禁止」什麼意思是「無論如何都拒絕訪問」。 – deamon

152

我推薦status code 422, "Unprocessable Entity"

11.2。 422不可處理實體

422(不可處理實體)狀態碼錶示服務器理解請求實體的內容類型(因此415(不支持的媒體類型)狀態碼不合適),並且請求實體的語法是正確的(因此400(錯誤請求)狀態碼不合適),但無法處理包含的指令。例如,如果XML請求主體包含格式正確的(即,,語法正確),但語義錯誤的XML指令。

+2

這不是http狀態碼 – deamon

+0

WebDAV擴展!好點,沒有想到這一點。 – Piskvor

+10

當然,它是一個HTTP狀態代碼,請參閱http://www.iana.org/assignments/http-status-codes。有更多的狀態碼比RFC 2616中定義的更多。 –

64

200,300,400,500都是非常通用的。如果你想通用,400是OK。

422被越來越多的API使用,甚至被Rails直接使用。

無論您爲API選擇哪種狀態碼,都會有人不同意。但我更喜歡422,因爲我認爲'400 +文本狀態'太泛泛。另外,您沒有充分利用JSON就緒解析器;相反,具有JSON響應的422非常明確,並且可以傳達大量的錯誤信息。

說到JSON響應,我傾向於在這種情況下,Rails的錯誤響應,這是規範:

{ 
    "errors" : 
    { 
     "arg1" : ["error msg 1", "error msg 2", ...] 
     "arg2" : ["error msg 1", "error msg 2", ...] 
    } 
} 

這種格式是完美的表單驗證,這是我認爲最複雜的情​​況下支持'錯誤報告豐富'的條款。如果你的錯誤結構是這樣的,它可能會處理你所有的錯誤報告需求。

+2

關於參數間相互作用引起的錯誤怎麼辦?也就是說,'arg1'是有效的,'arg2'是有效的,但是兩者的組合和發送的特定值是無效的。 – Jonah

+1

我不會認爲它;只是選擇一個似乎擁有這種關係的人。 – sethcall

+0

甚至只是兩個參數上的錯誤。作爲用戶,我想我想看到每個有衝突的字段上的錯誤。 – snuggles

6

Status Code 304 Not Modified也會對重複請求做出可接受的響應。這與使用實體標籤處理If-None-Match的標題類似。

在我看來,@ Piskvor的答案是更明顯的選擇,我認爲是原始問題的意圖,但我有一個也是相關的替代方案。

如果您想將重複請求作爲警告或通知而不是錯誤處理,則應答狀態碼304未修改,Content-Location標識現有資源的標題也同樣有效。當意圖僅僅是確保資源存在時,重複請求不會是錯誤而是確認。請求沒有錯,但是簡單多餘,客戶端可以參考現有資源。

換句話說,請求是好的,但由於資源已經存在,服務器不需要執行任何進一步的處理。

+4

這是我的理解,304是用於GET操作來協助緩存。 – Sinaesthetic

6

灰燼-Data的ActiveRecord的適配器預計422 UNPROCESSABLE ENTITY從服務器返回。所以,如果你的客戶端是用Ember.js編寫的,你應該使用422.只有這樣DS.Errors纔會填充返回的錯誤。 You can of course change 422 to any other code在您的適配器中。

4

啊...(309,400,403,409,415,422)......很多答案試圖猜測,爭論和規範什麼是最好的返回碼的一個成功的http請求失敗的其餘呼叫

這是錯誤混合HTTP協議代碼和REST結果。

但是,我看到很多實現混合它們,許多開發人員可能不同意我的看法。

HTTP返回碼與HTTP Request本身有關。 REST調用是使用超文本傳輸​​協議請求完成的,它的工作級別低於調用的REST方法本身。 REST是一個概念/方法,其輸出結果是業務/邏輯,而HTTP結果代碼是傳輸之一。

例如,返回 「404未找到」 當你調用/用戶/被迷惑,因爲這可能意味着:

  • URI是錯誤的(HTTP)
  • 沒有用戶發現(REST)

「403拒絕禁止/訪問」 可能意味着:

  • 需要特別許可。瀏覽器可以通過詢問用戶/密碼來處理它。 (HTTP)
  • 服務器上配置的訪問權限錯誤。 (HTTP)
  • 您需要進行身份驗證(REST)

這個名單可以繼續「500服務器錯誤」(一個Apache/Nginx的HTTP拋出錯誤或REST業務約束錯誤)或其他HTTP錯誤等等

從代碼,這是很難理解什麼是失敗的原因,一個HTTP(運輸)故障或REST(邏輯)失敗。

如果HTTP請求物理已成功對其執行應該總是返回200代碼,無論是記錄(S)發現與否。因爲URI資源是找到了並且由http服務器處理。是的,它可能會返回一個空集。是否有可能收到一個空的網頁與200作爲http結果,對不對?

取而代之的是,你可能會返回200 HTTP代碼的一些選項:

  • 在JSON結果「錯誤」的對象,如果出現錯誤
  • 空的JSON數組/對象,如果沒有找到記錄
  • 一布爾結果/成功標誌與以前的選項相結合,以獲得更好的處理。

此外,一些互聯網服務提供商可能會攔截您的請求並返回404 http代碼。這並不意味着你的數據沒有找到,但是在傳輸層面它是錯誤的。

Wiki

在2004年7月,英國電信運營商BT集團部署了Cleanfeed 內容屏蔽系統,該系統會返回一個404錯誤由互聯網觀察發現可能非法的 內容的任何請求 基金會。其他ISP在相同的 環境中返回HTTP 403「禁止」錯誤。在泰國和突尼斯,也有報道稱使用假404錯誤作爲隱藏審查的手段。在 2011年革命前審查嚴重的突尼斯 人們意識到假404錯誤的性質,並創建了一個名爲「Ammar 404」的假想字符,代表「隱形 檢查員」。

爲什麼不簡單地回答這樣的事情?

{ 
    "result": false, 
    "error": {"code": 102, "message": "Validation failed: Wrong NAME."} 
} 
+1

實際上,對REST使用HTTP狀態代碼更讓人困惑:1)您在開發人員的工具箱中看到了4xx,並且您無法僅通過查看服務器是否返回一些合理價值或無法處理您的請求所有,然後2)所有你的錯誤/異常/捕獲處理程序應該檢查什麼樣的服務器返回作爲響應(大多數情況下,他們不這樣做,因爲你必須在每次服務調用時都這樣做)並且多次3)您獲得相同的有效負載(類型)在成功和錯誤路徑導致複雜/重複代碼...確實很混亂。 – szczepanpp

+2

這個答案混淆了HTTP協議的原始語義,以及作爲_architectural style_的HTTP作爲REST如何重新實現HTTP服務以實現Web服務API。作爲一種架構風格,REST不是嚴格遵循的標準,而是一種建議的方法。使用200響應來驗證失敗是不對或錯的,但是您的客戶迴應請求成功但實際上由於驗證失敗而失敗,這是一個在響應主體中隱藏的重要細節,客戶必須解析的語義。 –

+0

@KevinHooke,這個答案認爲,爲什麼使用HTTP返回碼對於REST狀態調用來說是個壞主意。 – Marcodor