这是 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 语句应该发送什么样的响应?有关用户的信息?也许可以通过 ID 来通过其他 API 调用来操作它们?或者也许它应该只说“成功”或“失败:[错误详细信息]”?
The way I have understood idempotency thus far is basically: If I send 10 identical PUTs to a server the resulting additional resources created will be identical to if I had sent a single PUT statement.
What I take this to mean is that the following implementation would adhere to this:
[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");
}
There now if I sent 10 PUTs with XML for User data and they all contain the same e-mail address, only one user will be created.
However, what if they send 10 requests (for whatever reason) and they are all different, but the e-mail is the same. If the first request doesn't make it through then the data of the 2nd request will be used to create the user, and the following 8 requests will be ignored. Is there a flaw here? Or should I literally only ignore requests that are explicitly identical in every way and instead send back an error saying the user already exists if they use the same e-mail address?
Also, what kind of response should be sent from a such PUT statement? Info about the user? Maybe an ID to manipulate them with other API calls? Or perhaps it should just say "success" or "fail: [error details]"?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的问题没有透露 PUT 请求发送到的 URL。这实际上非常重要,因为决定是创建新资源还是更新旧资源的不是 XML 数据中的电子邮件地址,而是您向其发送请求的 URL。
因此,如果您将 PUT 发送到 /users/[email protected]/ 它创建用户 [电子邮件受保护] 或更新它(如果系统中已存在)。
类似地,如果您将 PUT 发送到 /users/123/ (使用 id 而不是电子邮件),它将创建或更新用户 123。但是,在这种情况下,如果电子邮件必须是唯一的并且有人发送 PUT /users/456/ 并在如果 XML 与用户 123 已有的电子邮件是同一封电子邮件,则您必须响应 409 冲突。
Your question doesn't reveal the URL where the PUT request is sent to. This is actually very important as it is not the email address within the XML data that dictates whether a new resource is created or an old one updated but the URL that you are sending the request to.
So, if you send PUT to /users/[email protected]/ it either creates the user [email protected] or updates it if it was already in the system.
Similaraly, if you send PUT to /users/123/ (using id instead of email) it will create or update user 123. However, in this case if the email has to be unique and somebody sends PUT /users/456/ and within that XML is the same email as what the user 123 already has, you have to respond with 409 Conflict.
如果用户已存在且具有相同的电子邮件地址,则第二次及后续 PUT 操作应更新该资源的数据。成功或失败应在状态代码中传达。如果更新成功,则回复“200 OK”,或者“204 No Content”;您可以返回一些信息,但不要期望缓存将其存储为您从 GET 获取的新表示形式。如果您不希望该资源接受除第一个操作之外的 PUT 操作,请使用“405 Method Not allowed”进行响应,并在响应正文中进行解释。如果提交的表示可能会替换资源,但由于其特定字段无法与现有状态一致而不能替换,请使用“409 冲突”(同样,在响应正文中进行解释)。
If the user already exists with the same email address, then the 2nd and subsequent PUT operations should update the data for that resource. The success or failure should be communicated in the status code. If the update succeeds, respond with "200 OK", or "204 No Content"; you can return some information, but don't expect caches to store it as if it were the new representation you would obtain from a GET. If you do not intend for that resource to ever accept a PUT operation other than the first one, then respond instead with "405 Method Not Allowed", with an explanation in the response body. Use "409 Conflict" (again, with an explanation in the response body) if the submitted representation might replace the resource, but can't because it's particular fields cannot be reconciled with the existing state.