I am wondering if my current approach makes sense or if there is a better way to do it.
I have multiple situations where I want to create new objects and let the server assign an ID to those objects. Sending a POST request appears to be the most appropriate way to do that. However since POST is not idempotent the request may get lost and sending it again may create a second object. Also requests being lost might be quite common since the API is often accessed through mobile networks.
As a result I decided to split the whole thing into a two-step process:
First sending a POST request to create a new object which returns the URI of the new object in the Location header.
Secondly performing an idempotent PUT request to the supplied Location to populate the new object with data. If a new object is not populated within 24 hours the server may delete it through some kind of batch job.
Does that sound reasonable or is there a better approach?
Idempotency is important in APIs because a resource may be called multiple times if the network is interrupted. In this scenario, non-idempotent operations can cause significant unintended side-effects by creating additional resources or changing them unexpectedly.
POST is NOT idempotent. GET , PUT , DELETE , HEAD , OPTIONS and TRACE are idempotent.
Post method always results in a server state change. If the POST method was idempotent, everything sent and accepted to or from the web server would already have to exist on the server in some form to respond with the same codes and value response. For that reason, POST cannot be idempotent.
Idempotent is where you call the same function with the same value and the result is exactly the same, that is the mathematically definition. If you ever update state then you are not idempotent, that its 'a database update' doesn't change anything.
The only advantage of POST-creation over PUT-creation is the server generation of IDs. I don't think it worths the lack of idempotency (and then the need for removing duplicates or empty objets).
Instead, I would use a PUT with a UUID in the URL. Owing to UUID generators you are nearly sure that the ID you generate client-side will be unique server-side.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With