當你看list of available HTTP status codes,你會在某個時刻認識到,有很多人,但單獨使用本身也不能真正解釋錯誤。
所以要回答你的問題,有兩個部分。一個是:你的API如何傳達錯誤的原因,並添加API的用戶(大多數情況下是另一個開發人員)可以閱讀和採取行動的有用信息。您應該儘可能多地添加機器可讀和人類可讀的信息。
另一部分:HTTP狀態代碼如何幫助區分某些錯誤(和成功)狀態?
這後一部分實際上比一件事情更難。有404個明顯的情況用於告訴「未找到」。而500是服務器端的任何錯誤。
我不會使用狀態401,除非我真的想讓操作在存在HTTP身份驗證憑證的情況下成功。 401通常會在瀏覽器中觸發一個對話框,這很糟糕。
如果資源是唯一且已存在的,狀態「409 Conflict」似乎是合適的。如果創建用戶成功,狀態「201 Created」聽起來也是一個好主意。
請注意,還有更多的狀態代碼,其中一些與HTTP協議的擴展(如DAV)有關,一些完全沒有標準化(例如狀態「420讓你的冷靜」從Twitter API中獲益)。看看http://en.wikipedia.org/wiki/List_of_HTTP_status_codes看看到目前爲止使用了什麼,然後決定是否要使用適合您的錯誤情況的東西。
根據我的經驗,簡單地選擇一個狀態碼並使用它是很容易的,但很難一致地按照現有標準進行操作。
我不會因爲別人會抱怨而停下來。 :)正確的做RESTful接口本身就是一項艱鉅的任務,但接口越多,獲得的經驗就越多。
編輯:
關於版本的:它被認爲是不好的做法,把一個版本標記到URL,像這樣:example.com/api/v1/stuff
它會工作,但它是不是很好。
但首先是:您的客戶如何指定他想要獲得哪種表示形式,即他如何決定要麼獲取JSON或XML?答案:Accept
標題。他可以爲JSON發送Accept: application/json
,爲XML發送Accept: application/xml
。他甚至可能接受多種類型,並且服務器決定返回什麼。
除非服務器被設計爲回答多個資源表示(JSON或XML,客戶端選擇),否則客戶端的確沒有多少選擇。但讓客戶至少發送「application/json」作爲他的唯一選擇,然後返回標題Content-type: application/json
作爲迴應,這仍然是件好事。這樣,雙方都明確表示他們希望對方看到內容。
現在的版本。如果將版本放入URL中,則可以有效地創建不同的資源(v1和v2),但實際上,只有一個資源(= URL)使用不同的方法來訪問它。當請求的參數和/或與當前版本不兼容的響應中的表示發生突變時,必須創建API的新版本。
因此,當您創建使用JSON的API時,您不會處理泛型JSON。你處理一個具體的JSON結構,它對你的API來說是獨一無二的。您可以也可能應該在服務器發送的Content-type
中指出這一點。 「供應商」的擴展是這樣的:Content-type: application/vnd.IAMVENDOR.MYAPI+json
會告訴世界,基本的數據結構是application/json,但它是你的公司和你的API,真正地告訴哪個結構期望。而這正是API請求的版本適合的地方:application/vnd.IAMVENDOR.MYAPI-v1+json
。
因此,不要將版本放入URL中,而是期望客戶端發送Accept: application/vnd.IAMVENDOR.MYAPI-v1+json
標題,並且您也以Content-type: application/vnd.IAMVENDOR.MYAPI-v1+json
作爲響應。這對第一個版本確實沒有什麼影響,但讓我們看看版本2發揮作用時的情況。
URL方法將創建一組完全不相關的新資源。客戶端會懷疑example.com/api/v2/stuff
與example.com/api/v1/stuff
的資源是否相同。客戶端可能已經使用v1 API創建了一些資源,並且存儲了這些東西的URL。他應該如何將所有這些資源升級到v2?資源真的沒有改變,它們是一樣的,唯一改變的是它們在v2中看起來不同。
是的,服務器可能會通過發送重定向到v2 URL來通知客戶端。但重定向並不表示客戶端還必須升級API的客戶端部分。
對版本使用accept標頭時,資源的URL對於所有版本都是相同的。客戶端決定使用版本1或2請求資源,服務器可能如此友善,仍然可以回答版本1請求的版本1響應,但所有版本2的請求都帶有新的閃亮的版本2響應。
如果服務器無法應對版本1請求,他可以通過發送HTTP狀態「406不可接受」來告訴客戶端(請求的資源只能根據發送的接受頭文件生成不可接受的內容請求。)
客戶端可以發送包含兩個版本的accept頭,這使得服務器可以使用他最喜歡的版本進行響應,即智能客戶端可以實現版本1和版本2,並且現在將兩者都作爲accept頭髮送,並等待以便服務器從版本1升級到2.服務器會在每個響應中告訴它是版本1還是版本2,並且客戶端可以採取相應措施 - 他不需要知道服務器版本升級的確切日期。
總結一下:對於一個非常基本的API,即使有一個版本也許是有限的,可能是內部的,但是使用起來可能會過度。但是你永遠不知道這一年是否會成爲現實。將版本號包含到API中始終是一個非常好的主意。最好的地方在於您的API即將使用的mime類型。檢查單個現有版本應該是微不足道的,但您可以選擇稍後進行透明升級,而不會混淆現有客戶端。
restful api只是爲我自己的網站的ajax/backbonejs/jquery使用。在這種情況下,我應該堅持相同的錯誤代碼(比如400)嗎?或者爲每個AJAX響應返回200,並檢查'success'變量以查看是否發生錯誤 – Nyxynyx 2013-03-24 15:50:03
不,通過錯誤代碼指示基本的「成功/錯誤」事實是一個非常好的主意。錯誤響應由HTTP客戶端處理,例如,它們不應該被緩存等。在數據有效載荷內指示相同也是一件好事。我自己的API在成功時有「數據」,或者在失敗時有「錯誤」。這與「成功=真/假」基本相同,並且適用於我。但是確實知道狀態「400錯誤請求」不是您認爲的通用客戶端錯誤狀態。沒有這樣的事情,你必須指定錯誤狀態。 – Sven 2013-03-24 16:28:24
很好的答案,斯文! 但是,您會說:>關於版本控制:將版本 >標記放入我不同意的網址中被認爲是不好的做法。這是Apigee的一個[指南](http://apigee.com/about/api-best-practices/restful-api-design-second-edition),他得出結論認爲* *確實是最佳的使用版本號的做法網址。他們還澄清了返回狀態代碼。 – unicopter 2013-04-10 19:27:14