2011-06-07 303 views
0

到目前爲止,我瞭解冪等性的方式基本上是:如果我向服務器發送10個相同的PUT,則創建的附加資源將與我發送單個PUT語句時相同。這是PUT冪等性的正確實現,應該是什麼?

我藉此什麼意思是,下面的實現會堅持這樣的:

[AcceptVerbs(HttpVerbs.Put)] 
ContentResult User(){ 

    //parse XML that was sent to get User info 
    //User has an e-mail address which is unique to the system 
    //create a new user in the system only if one for this e-mail address does not exist 

    return Content(something, "text/xml"); 
} 

有現在如果我派10個PUT操作與XML的用戶數據,它們都包含相同的E-mail地址,只有一個用戶將被創建。

但是,如果他們發送10個請求(無論出於何種原因)又會如何,他們都是不同的,但電子郵件是相同的。如果第一個請求沒有通過,那麼第二個請求的數據將被用於創建用戶,並且以下8個請求將被忽略。這裏有缺陷嗎?或者,我應該字面上只忽略明確相同的請求,而是發送一個錯誤,說如果用戶使用相同的電子郵件地址,則該用戶已存在?

此外,應該從這樣的PUT語句發送什麼樣的響應?關於用戶的信息?也許一個ID來操縱他們與其他API調用?或者,也許它應該只是說「成功」或「失敗:[錯誤詳情]」?

回答

0

如果用戶已經存在相同的電子郵件地址,則第二個和後續的PUT操作應更新該資源的數據。成功或失敗應在狀態代碼中傳達。如果更新成功,則以「200 OK」或「204 No Content」響應;你可以返回一些信息,但不要指望緩存存儲它,就好像它是你從GET獲得的新的表示。如果您不打算讓該資源接受除第一個外的其他PUT操作,那麼請回答「405方法不允許」,並在響應主體中進行說明。如果提交的表示可能會替換資源,則使用「409衝突」(同樣在響應主體中進行說明),但不能因爲它的特定字段不能與現有狀態一致。

2

你的問題沒有顯示發送PUT請求的URL。這實際上非常重要,因爲它不是XML數據中的電子郵件地址,它指示是創建新資源還是更新舊資源,而是要發送請求的URL。

因此,如果您將PUT發送到/users/[email protected]/,它可以創建用戶[email protected],或者如果它已經在系統中,則更新它。

同樣,如果您發送PUT到/ users/123 /(使用id而不是電子郵件),它將創建或更新用戶123.但是,在這種情況下,如果電子郵件必須是唯一的,並且有人發送PUT/users/456 /並且在該XML中與用戶123已有的電子郵件相同,則必須使用409衝突進行響應。

+0

我同意;我認爲關鍵的一點是用作身份的數據點,以及可能發生的衝突。 – 2011-06-07 23:27:28

+0

有趣的是,如果他們正在創建一個用戶,我還不知道該ID,但是如果我正在檢查URL或者我正在檢查數據,因爲它將在代碼中相同,我仍然不確定它的重要性,如果它匹配它不是新的。 – BigOmega 2011-06-08 13:13:33