I like your approach/idea but I didn't understand how you apply it to the "duplicate payment problem"
If I understood correctly you say that we should issue a POST to get the final resource id/url, and then PUT the request BUT if it's a payment transaction with a network error, doesn't it result in the same problem?
CLIENT: POST /payments/new
SERVER: HERE YOU ARE THE ID
CLIENT: PUT /payments/123
let's assume now there's a network error and the client doesn't know if it's PUT went through or not so it decides to resubmit it, thinking that PUT, being idemponent, is safe.
Aren't we still left with 2 payments?
Let me explain: HTTP says PUT should be idempotent (so without side effects and with the same result). This is fine to update a record or an image or whatever but a payment it's not a side effect free operation.
So if I try two times to PUT the payment and the server both times issues a payment to the third party, I'm still left with double the amount less in my account.
About me: software developer who is into JavaScript and NodeJS and constantly working on one or another side project and/or open source. I have a blog at https://alex-rudenko.com
In the case of PUT operation, the server can easily check if a payment has been already sent for this particular payment id. When the server gets a new PUT request, it checks if the payment has been sent to a 3rd party and never sends it twice (this can be ensured internally via locks and/or transactions). For POST requests it's not that easy because it's hard to know the intent of the caller (whether it's a duplicate request or a new payment). Therefore, you need to come up with less elegant solutions such as adding a RequestId header and by this you shift the responsibility to the caller.
About me: software developer who is into JavaScript and NodeJS and constantly working on one or another side project and/or open source. I have a blog at https://alex-rudenko.com
I see that Stripe API uses "Idempotency IDs" which allows the client to tell the server "Hey, this POST request is idempotent, treat it as such"
To perform an idempotent request, provide an additional Idempotency-Key: header to the request.
How you create unique keys is up to you, but we suggest using V4 UUIDs or another appropriately random string. We'll always send back the same response for requests made with the same key, and keys can't be reused with different request parameters. Keys expire after 24 hours.
I like your approach/idea but I didn't understand how you apply it to the "duplicate payment problem"
If I understood correctly you say that we should issue a POST to get the final resource id/url, and then PUT the request BUT if it's a payment transaction with a network error, doesn't it result in the same problem?
let's assume now there's a network error and the client doesn't know if it's PUT went through or not so it decides to resubmit it, thinking that PUT, being idemponent, is safe.
Aren't we still left with 2 payments?
Let me explain: HTTP says PUT should be idempotent (so without side effects and with the same result). This is fine to update a record or an image or whatever but a payment it's not a side effect free operation.
So if I try two times to PUT the payment and the server both times issues a payment to the third party, I'm still left with double the amount less in my account.
In the case of PUT operation, the server can easily check if a payment has been already sent for this particular payment id. When the server gets a new PUT request, it checks if the payment has been sent to a 3rd party and never sends it twice (this can be ensured internally via locks and/or transactions). For POST requests it's not that easy because it's hard to know the intent of the caller (whether it's a duplicate request or a new payment). Therefore, you need to come up with less elegant solutions such as adding a
RequestId
header and by this you shift the responsibility to the caller.Oh now I got it, thanks! You use the id on the server instead of a generic "request id" on the client to shift responsibility.
I thought you were trying to do that still keeping the responsibility on the client, that's why I didn't understand.
Thanks! :-)
Have you ever dealt with the problem of duplicate requests yourself? If so, how?
Yep, but using request ids, not really handy.
I see that Stripe API uses "Idempotency IDs" which allows the client to tell the server "Hey, this POST request is idempotent, treat it as such"
See stripe.com/docs/api#idempotent_req... and masteringmodernpayments.com/blog/i...