2012-02-21 218 views
58

我正在創建一個RESTful API,它將處理大量的用戶交互,包括使用存儲的信用卡下訂單。對於一般不成功的請求(不是錯誤),適當的HTTP狀態碼響應是什麼?

如果訂單成功,我將返回200 OK,並且在訂單請求格式不正確或無效的情況下,我將返回400錯誤請求。但是,如果在訂單的實際處理過程中出現問題,我應該返回什麼?

  1. 客戶端向服務器發送用戶資源的POSTS命令。如果用戶不存在,則返回404 Not Found。
  2. 訂單格式和信息經過驗證。如果無效,則返回400錯誤請求。
  3. 訂單已處理。如果訂單成功,則會爲訂單返回201 Created。如果遇到意外錯誤,則返回500服務器錯誤。

最後一步是問題 - 如果訂單因任何其他原因未能完成,我將返回什麼?可能出現的情況可能包括:

  • 產品已經賣完了
  • 用戶最大訂單數量已達到上限
  • 信用卡交易失敗(資金不足等)

這似乎並不像它適用於400或500.如果沒有更好的代碼,我可以將其視爲400 - 根據業務規則,請求無效。這似乎並不準確。

編輯:還找到相同主題的this existing discussion。所有的答案似乎都指向使用狀態代碼來處理這種違規行爲,並且在使用400,409或422擴展之間進行了一些討論。

+3

我喜歡 '422無法處理的實體' 驗證錯誤。如果客戶需要根據回覆以編程方式作出不同的決定 – house9 2015-10-16 00:19:22

回答

54

您應該使用400作爲業務規則。如果訂單未被接受,請不要退回2xx。 HTTP是一種應用協議,永遠不會忘記這一點。如果你返回2xx,客戶可以假定訂單已被接受,而不管你在正文中發送的任何信息。


RESTful Web Services Cookbook

一個常見的錯誤,有些網絡服務提出的是,返回狀態 碼反映成功(從200到206和300 到307狀態碼),但包括郵件正文描述了一個錯誤條件。這樣做可以防止HTTP感知軟件檢測到錯誤。例如,對於 示例,即使客戶端可能能夠成功請求 請求,緩存也會將其存儲爲成功響應並將其提供給後續客戶端 。

我會讓你決定在4xx和5xx之間,但你應該使用錯誤狀態碼。

+1

您會在實際業務問題的回覆中包含一條消息「產品已售罄」,並可能添加您自己的「代碼」有沒有這種方法相對於其他方面的例子或參考?你和Widor的答案都是有道理的,從HTTP作爲應用協議的角度來看,另一個是嚴格意義上的傳輸。該規範將其定義爲「應用程序級協議」,這有點含糊。在研究這件事時,我也看到了網絡上的兩個觀點和例子。 – Raelshark 2012-02-21 21:27:33

+0

這是如此的真實。 – 2017-11-20 13:29:11

15

如果客戶端可以修改請求以避開錯誤,則應該使用4xx作爲客戶端錯誤。使用5xx作爲客戶端無法真正解決的服務器錯誤。

產品售罄將是服務器錯誤。客戶端無法以某種方式修改請求以避開錯誤。你可以切換到另一個產品,但不會是一個新的要求?

達到的用戶最大訂單限制也是服務器錯誤。客戶無法解決該錯誤。

信用卡交易失敗將是一個客戶端錯誤。客戶可以用不同的付款方式或信用卡號碼重新提交請求以解決錯誤。

+3

如果達到訂單限額,客戶是否不應該提醒用戶,並讓他們適當地更改他們的請求?這似乎是一個4xx錯誤。產品售完也一樣。 5xx錯誤旨在用於由系統以某種方式分解導致的錯誤,而不是針對業務規則禁止的操作。 – 2015-12-14 19:35:04

+3

我同意上面的評論。 5xx錯誤是服務器出現問題時的錯誤。針對業務規則的4xx錯誤。 – Merc 2017-02-19 06:39:31

2

我不認爲400可以用於所有業務場景。它可以用於基本的數據輸入驗證。除此之外,我們可能很難將其他業務邏輯納入此錯誤代碼。由此處理的錯誤主要是開發人員在編碼客戶端時可能遇到的設計時錯誤。

假設所有參數都是正確的,假設我們將用戶帳號傳遞給請求。

所以請求現在不再是一個錯誤的請求,服務器能夠接受請求。但是現在它拒絕根據可用的新信息完成請求 - 這是賬戶沒有足夠的餘額。

我建議我們應該在這些情況下使用403與適當的錯誤消息。

其他可能的錯誤代碼可能是409衝突。但是,這用於資源處於一致狀態的情況。

5

我知道這個問題很老,但我今天提出了同樣的問題。如果我的用戶信用不足,我的REST API應該返回什麼狀態碼?

我往往傾向於402 Payment Required瘦:

根據Wikipedia

保留供未來使用。最初的意圖是這個代碼可能被用作某種形式的數字現金或微支付方案的一部分,但這並沒有發生,而且這種代碼通常不被使用。如果某個開發人員超出了每日請求限制,Google Developers API會使用此狀態。

事實上they do

PAYMENT_REQUIRED(402)

  • 每日預算由開發人員設置已經達到極限。
  • 請求的操作需要比配額允許的更多資源。需要付款才能完成操作。
  • 請求的操作需要經過身份驗證的用戶進行某種付款。
10

錯誤類型:

4×× Client Error 

錯誤代碼:

422 Unprocessable Entity 

的服務器理解的請求實體(因此一個415不支持的媒體類型的狀態代碼是不適當的)的內容類型,並且請求實體的語法是正確的(因此400錯誤請求狀態代碼是不恰當的),但無法處理包含的指令。

例如,如果XML請求主體包含格式正確(即,語法正確)但語義錯誤的XML指令,則可能會出現此錯誤情況。

https://httpstatuses.com/422

2

我去406 Not Acceptable

這裏有一個4XX列表:

const HTTP_BAD_REQUEST = 400; 
const HTTP_UNAUTHORIZED = 401; 
const HTTP_PAYMENT_REQUIRED = 402; 
const HTTP_FORBIDDEN = 403; 
const HTTP_NOT_FOUND = 404; 
const HTTP_METHOD_NOT_ALLOWED = 405; 
const HTTP_NOT_ACCEPTABLE = 406; 
const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407; 
const HTTP_REQUEST_TIMEOUT = 408; 
const HTTP_CONFLICT = 409; 
const HTTP_GONE = 410; 
const HTTP_LENGTH_REQUIRED = 411; 
const HTTP_PRECONDITION_FAILED = 412; 
const HTTP_REQUEST_ENTITY_TOO_LARGE = 413; 
const HTTP_REQUEST_URI_TOO_LONG = 414; 
const HTTP_UNSUPPORTED_MEDIA_TYPE = 415; 
const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416; 
const HTTP_EXPECTATION_FAILED = 417; 
const HTTP_I_AM_A_TEAPOT = 418;            // RFC2324 
const HTTP_MISDIRECTED_REQUEST = 421;           // RFC7540 
const HTTP_UNPROCESSABLE_ENTITY = 422;          // RFC4918 
const HTTP_LOCKED = 423;              // RFC4918 
const HTTP_FAILED_DEPENDENCY = 424;           // RFC4918 
const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425; // RFC2817 
const HTTP_UPGRADE_REQUIRED = 426;           // RFC2817 
const HTTP_PRECONDITION_REQUIRED = 428;          // RFC6585 
const HTTP_TOO_MANY_REQUESTS = 429;           // RFC6585 
+3

儘管狀態碼406的名稱本身可能聽起來很準確,但您需要知道,每個狀態碼都具有權威的文字說明。狀態碼406 *的描述不適合當前的情況。例如,請參閱https://httpstatuses.com/406。 – Zero3 2017-01-27 15:46:46

+0

@ Zero3是正確的,此代碼意味着響應類型是不可接受的,因爲客戶端發送的Accept Header和端點發送的MediaType之間存在不匹配。 application/json與text/plain – Gregor 2018-02-15 17:42:33

相關問題