Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid duplicate POSTs with REST

Tags:

rest

post

atomic

I have been using POST in a REST API to create objects. Every once in a while, the server will create the object, but the client will be disconnected before it receives the 201 Created response. The client only sees a failed POST request, and tries again later, and the server happily creates a duplicate object...

Others must have had this problem, right? But I google around, and everyone just seems to ignore it.

I have 2 solutions:

A) Use PUT instead, and create the (GU)ID on the client.

B) Add a GUID to all objects created on the client, and have the server enforce their UNIQUE-ness.

A doesn't match existing frameworks very well, and B feels like a hack. How does other people solve this, in the real world?

Edit:

With Backbone.js, you can set a GUID as the id when you create an object on the client. When it is saved, Backbone will do a PUT request. Make your REST backend handle PUT to non-existing id's, and you're set.

like image 561
geon Avatar asked Mar 01 '13 13:03

geon


People also ask

How do I prevent duplicates in spring boot?

There are different ways to avoid double submits, which can be combined: Use JavaScript to disable the button a few ms after click. This will avoid multiple submits being caused by impatient users clicking multiple times on the button. Send a redirect after submit, this is known as Post-Redirect-Get (PRG) pattern.

How do you avoid multiple requests to API within a given time?

Step.2 - Define child routes in parent component html That's it. On clicking on tabs you interchange state and you use ngOnInit() method every time when a state is changed to get the data.In this way, you can reduce API calls by using nested routing.

How do I avoid the same request for multiple times to the server?

You can't stop the user from resubmitting a new request with the same ticket, but you can reject it on the server side, with a "Duplicate request" error. Right, but people do that on purpose - submit a form, press back because they know they need to correct something, submit form again.


3 Answers

Another solution that's been proposed for this is POST Once Exactly (POE), in which the server generates single-use POST URIs that, when used more than once, will cause the server to return a 405 response.

The downsides are that 1) the POE draft was allowed to expire without any further progress on standardization, and thus 2) implementing it requires changes to clients to make use of the new POE headers, and extra work by servers to implement the POE semantics.

By googling you can find a few APIs that are using it though.

Another idea I had for solving this problem is that of a conditional POST, which I described and asked for feedback on here.

There seems to be no consensus on the best way to prevent duplicate resource creation in cases where the unique URI generation is unable to be PUT on the client and hence POST is needed.

like image 200
Chris Toomey Avatar answered Oct 19 '22 11:10

Chris Toomey


I always use B -- detection of dups due to whatever problem belongs on the server side.

like image 11
Kyle Banerjee Avatar answered Oct 19 '22 12:10

Kyle Banerjee


Detection of duplicates is a kludge, and can get very complicated. Genuine distinct but similar requests can arrive at the same time, perhaps because a network connection is restored. And repeat requests can arrive hours or days apart if a network connection drops out.

All of the discussion of identifiers in the other anwsers is with the goal of giving an error in response to duplicate requests, but this will normally just incite a client to get or generate a new id and try again.

A simple and robust pattern to solve this problem is as follows: Server applications should store all responses to unsafe requests, then, if they see a duplicate request, they can repeat the previous response and do nothing else. Do this for all unsafe requests and you will solve a bunch of thorny problems. Repeat DELETE requests will get the original confirmation, not a 404 error. Repeat POSTS do not create duplicates. Repeated updates do not overwrite subsequent changes etc. etc.

"Duplicate" is determined by an application-level id (that serves just to identify the action, not the underlying resource). This can be either a client-generated GUID or a server-generated sequence number. In this second case, a request-response should be dedicated just to exchanging the id. I like this solution because the dedicated step makes clients think they're getting something precious that they need to look after. If they can generate their own identifiers, they're more likely to put this line inside the loop and every bloody request will have a new id.

Using this scheme, all POSTs are empty, and POST is used only for retrieving an action identifier. All PUTs and DELETEs are fully idempotent: successive requests get the same (stored and replayed) response and cause nothing further to happen. The nicest thing about this pattern is its Kung-Fu (Panda) quality. It takes a weakness: the propensity for clients to repeat a request any time they get an unexpected response, and turns it into a force :-)

I have a little google doc here if any-one cares.

like image 9
bbsimonbb Avatar answered Oct 19 '22 13:10

bbsimonbb