Lets say we have an API that receives requests to commit a money transaction.
The API receives the requests from a certain client and calls for a certain 3rd party service (lets say provided by the bank - call it
bank service) to commit the transaction.
We choose to implement the API in a way that all of its endpoints are idempotent.
Why? well lets imagine a case where we have a transaction that is committed, meaning that the API made a successful request to the
bank service but before managing to send the client that made the request that everything is good, it crashed.
If our API is idempotent, the client will be able to send as many requests to perform the (same) transaction over and over until he receives an answer that he is satisfied with.
If my API has to be idempotent, I have to save the
idempotency key and its result in some sort of DB so I will know what happen with that request.
In the same time, I also have to perform the call for the
bank service and see if it succeeds.
This means that I have to perform an atomic action but with two point of failure that are not on the save server, some sort of distributed transaction.
I cant let the API be in a position that the request that came back from the
bank service doesn't go into the store of the
idempotency keys because of some failure (be it in the hardware or software).
The questions: How can I make this work, making sure that the call for the committing of the money transaction and the inserting of the result of it to some sort of DB is atomic?
Maybe there is another way which I am not aware of to tackle this kind of problem?
Maybe all of the companies that handle money transaction already use a
bank service that has an idempotent API which results in a much easier work? It is much easier to implement an atomic and idempotent API if you have the direct access to the money DB.