DEV Community

Discussion on: Making Better HTTP APIs

Collapse
 
rhymes profile image
rhymes

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.

Collapse
 
orkon profile image
Alex Rudenko • Edited

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.

Collapse
 
rhymes profile image
rhymes

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! :-)

Thread Thread
 
orkon profile image
Alex Rudenko

Have you ever dealt with the problem of duplicate requests yourself? If so, how?

Thread Thread
 
rhymes profile image
rhymes • Edited

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"

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.

See stripe.com/docs/api#idempotent_req... and masteringmodernpayments.com/blog/i...