这是PUT幂等性的正确实现吗?响应应该是什么?

时间:2011-06-07 15:14:47

标签: asp.net-mvc api http rest put

到目前为止,我理解幂等性的方式基本上是:如果我向服务器发送10个相同的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个带有XML用户数据的PUT,并且它们都包含相同的电子邮件地址,则只会创建一个用户。

然而,如果他们发送了10个请求(无论出于何种原因)并且它们都不同,但电子邮件是相同的。如果第一个请求没有通过,则第二个请求的数据将用于创建用户,并且将忽略以下8个请求。这里有缺陷吗?或者我字面上只应忽略在各方面明确相同的请求,而是发回一个错误,说如果用户使用相同的电子邮件地址已经存在?

此外,应该从这样的PUT声明发送什么样的响应?有关用户的信息?也许是用其他API调用来操纵它们的ID?或者它应该只是说“成功”或“失败:[错误细节]”?

2 个答案:

答案 0 :(得分:2)

您的问题未显示发送PUT请求的网址。这实际上非常重要,因为XML数据中的电子邮件地址并不是指示是创建新资源还是更新旧资源,而是更新您发送请求的URL。

因此,如果您将PUT发送到/users/jonh.doe@foo.com/,它会创建用户john.doe@foo.com,或者如果它已经在系统中则更新它。

Similaraly,如果您将PUT发送到/ users / 123 /(使用id而不是电子邮件),它将创建或更新用户123.但是,在这种情况下,如果电子邮件必须是唯一的,并且有人发送PUT / users / 456 /并且在该XML内是与用户123已经拥有的电子邮件相同的电子邮件,您必须回复409冲突。

答案 1 :(得分:0)

如果用户已经存在相同的电子邮件地址,则第二次和后续PUT操作应更新该资源的数据。成功或失败应在状态代码中传达。如果更新成功,请回复“200 OK”或“204 No Content”;您可以返回一些信息,但不要指望缓存存储它,就像它是您从GET获得的新表示一样。如果您不打算让该资源接受除第一个以外的PUT操作,则使用“405 Method Not Allowed”进行响应,并在响应正文中作出解释。如果提交的表示可能替换资源,则使用“409 Conflict”(再次,在响应正文中有解释),但不能,因为它的特定字段无法与现有状态协调。