开发者

Is this a proper implementation of PUT idempotency and what should the response be?

开发者 https://www.devze.com 2023-03-10 20:09 出处:网络
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 statemen

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 manip开发者_StackOverflow社区ulate them with other API calls? Or perhaps it should just say "success" or "fail: [error details]"?


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/jonh.doe@foo.com/ it either creates the user john.doe@foo.com 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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消