[英]REST design - An operation with multiple possible non-success payloads
我正在嘗試為具有一堆業務規則的“添加人”操作設計REST方法。 存在多個可能的非成功有效載荷(出於商業目的),需要定義的結構(以允許消費者解析細節)。
對於“添加一個人”,可能會發生以下不成功之一:
問題 - 響應對象
如果他們都要在一個HTTP錯誤狀態代碼下返回,那么擁有一個變化的對象是否正確:
消費者+文檔是否解釋了解釋?
問題 - 響應代碼
400(錯誤請求)是否正確(或足夠正確)HTTP狀態代碼? 我們主要用於現場驗證(也是場景(3) - 只是想知道這樣的業務規則/'中間狀態'是否有所不同。
是否有更合適的代碼來傳播3x場景? 有效載荷是否可以不同?
謝謝。
您需要考慮兩個方面
點號1相對簡單。 您有400個錯誤代碼用於錯誤請求。 409用於沖突資源。 到目前為止簡單。
現在讓我們考慮一下你的場景:
- 我們相信系統已經有了人。 有效負載:該人的ID
設計建議:您可以發送如下的回復
Response code: 409
{
"error_code": "resource_exists",
"error_description": "Resource person with ID XXX already exists"
"debug_info": "",
"link" : [
{
"href": "http://host-name/persons/123456",
"rel": "person"
}
]
}
2. There are some possible matches.
Payload: A list of possible duplicates, and an override code to submit the record 'for sure'
設計建議:在這種情況下 - 您可能希望使用PUT來覆蓋資源。 無需使用特殊代碼。
Response Code: 400
{
"error_code": "potential_duplicates",
"error_description": "Potentially the resource is duplicate of one of the following. Please use PUT with the resource ID to update"
"debug_info": "",
"link" : [
{
"href": "http://host-name/persons/234",
"rel": "person"
},
{
"href": "http://host-name/persons/456",
"rel": "person"
},
{
"href": "http://host-name/persons/789",
"rel": "person"
}
]
}
- 常規驗證錯誤Payload:“錯誤”對象的數組。 (API的標准)
設計建議:在這里你可以簡單地使用400響應代碼和一個有意義的響應,如上面的例子。
您可以使用409作為重復條目 - 並且可以說是可能的重復條目以及有效負載中的額外信息。
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.10
驗證錯誤400將是預期的響應。
這是一天結束時的判斷,這取決於你的休息客戶和他們正在做什么會更容易。
這是我在為錯誤情況創建RESTful API響應時使用的設計過程:
設計錯誤條件的響應有效負載。 無論使用何種錯誤代碼,最好在錯誤響應中返回一些內容,以便客戶可以了解有關錯誤的更多信息以及將來如何避免錯誤。
如果存在准確描述此錯誤的HTTP狀態代碼,並且尚未將其用於其他錯誤情況,請使用該狀態代碼。
如果最接近的匹配錯誤代碼已經用於另一個錯誤情況,那么使用該代碼仍然可以,但響應有效負載將成為該代碼下的不同錯誤情況彼此區分的地方。 您的文檔應該清楚地說明檢查此代碼是不夠的,然后客戶端也應該查看響應以確切了解發生了什么。
如果以上都不適用,請使用最合適的最接近的錯誤代碼。 就像在#3中一樣,響應有效負載的文檔使這種方法成為可能。 如果是客戶端影響的錯誤,則將其設為400范圍錯誤,可能為400 - Bad Request
。 如果是服務器的故障,那么它應該是500范圍的錯誤,可能是500 - Internal Server Error
。
拜托, 請永遠不要扔200 - OK
錯誤。 世界在肥皂土地上留下了廢話,沒有人願意回去。
現在讓我們將這種想法應用於您的錯誤案例:
We believe the system already has that person.
正如在另一個答案中正確陳述的那樣, 409 - Conflict
准確地描述了該錯誤,因此您應該使用它。 在響應有效負載中添加一些描述性錯誤信息將有助於API的新用戶,即使有這樣一個明確且易於理解的代碼。
There are some possible matches.
確實沒有描述這個的HTTP代碼,而且它是客戶端可以影響的東西,所以最接近的是400 - Bad Request
的全能代碼。 包括可能重復的列表是一個有趣的想法,但請確保您最終不會返回大量可能匹配的大量響應。 此外,請確保還將URI返回給那些匹配的資源,以便您的客戶可以輕松使用它們。 至於“覆蓋代碼”建議,我不會在有效負載中返回。 相反,我只是將一個參數記錄到你的“添加一個人”操作,該操作允許在任何時候發生覆蓋,而不僅僅是在第一次嘗試失敗之后。 例如: POST /people?overwrite=true
。
General validation errors
這絕對是400 - Bad Request
,以及描述性錯誤有效負載。 聽起來你已經允許從任何API調用返回一系列錯誤,因此它應該足以捕獲客戶端提供的數據的所有驗證失敗。
這部分取決於操作的執行方式。 既然你說操作有一堆業務規則,並且當人已經存在時系統返回帶有ID的有效負載,那么我們假設由於不相關的副作用,操作是非冪等的,使用POST到工廠端點執行。
我們相信系統已有人。
這是一個明智的做法。 正如其他人所建議的那樣,您應該使用409 Conflict
狀態代碼,其中一個主體描述沖突的性質。 在這種情況下,似乎沒有其他用戶需要做的事情,他可以繼續前進到工作流程的下一步。 如果他能做什么,它應該遵循類似於下一個案例的程序。
2.有一些可能的比賽。
假設客戶端沒有明確標識某個人的任何密鑰,這似乎是您的情況,因為您正在考慮可能的匹配,在這里您還應該使用409 Conflict
狀態代碼,其中一個主體描述沖突的性質,但有關於如何解決它的說明。
其他一些答案建議你允許一個可以隨時使用的覆蓋參數,其他建議使用PUT
,但我不同意,因為沒有什么能阻止客戶端一直使用覆蓋,或者跳過POST
並使用PUT
替換現有的近距離比賽。 此外,您可能有並發客戶端嘗試添加或更改彼此匹配的人員或共同存在的組,這將導致ABA沖突。
沖突解決主體應為每個可能的匹配返回有效標記,並且應指示客戶端使用If-Match
標頭和標記集合重新提交相同的請求。 它可以是單個標記,只要它是從集合中每個成員的密鑰數據生成的。 這將強制用戶首先必須嘗試請求而不進行任何覆蓋。 如果存在沖突,則用戶被迫指定將被覆蓋的確切實體,並且如果有人更改了第一個和第二個請求之間的當前狀態,則會保護您免受不一致的更新。
如果標記在第二個請求中不匹配,意味着狀態由它們之間的其他內容更改,則應該失敗並顯示412 Precondition Failed
錯誤。
3.一般驗證錯誤
這也是一個明智的選擇。 400 Bad Request
詳細說明了錯誤,這似乎是您的API的標准。
如何用有效載荷來解釋它; 這就是我們如何處理客戶端的REST響應。
響應HTTP 409,跟隨有效負載響應,向客戶端指示他們接下來應該做什么
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<request-result>
<http-code>200</http-code>
<description>REST Request is successfully processed</description>
<internal-error-info>Person already Exists</internal-error-info>
<message>Person with <id> already exists in sytem. Try picking different ID/Name combination</message>
<requested-operation>Add a Person</requested-operation>
<resource-name>Person</resource-name>
<status>SUCCESSFUL</status>
</request-result>
`
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.