Let’s get into the theory about idempotency before applying it in a practical example, even because after understanding what idempotency is, you may OR may not apply it depending on your situation.
What is idempotency?
Idempotency is the property that allows an operation to be applied more than once without changing the result.
Where to apply idempotency becomes interesting?
When there is the possibility of duplicate processing of information, where will cause problems of inconsistency (mainly in business).
In the case of asynchronous communications, the term Idempotency Messages, where together with the message a property is sent (an ID or a token), which will only identify the message.
You can check through this property if the message has already been processed (or not checked), and handle accordingly (just ignore the message or reprocess)
Another example would be when there was a request failure, and you are not sure if your request was actually met by the server, imagine the following scenario:
1) (Saldo total) R$1000,00
2) Transferência de R$100,00 para minha conta (POST /transfers?amount=100)
3) 200 OK | (Saldo total) R$900,00
4) Transferência de R$900,00 para minha conta (POST /transfers?amount=900)
5) CONNECTION TIMEOUT | (Saldo total) ?
6) Transferência de R$900,00 para minha conta (POST /transfers?amount=900)
7) 200 OK | (Saldo total) -R$900,00
When there was a timeout in the connection, we did not have the answer if the operation was performed or not, in our case the server had already processed and discounted R $ 900,00, leaving our account zero. A new request made another transfer of R $ 900,00, leaving our account negative.
For this example, if there was an idempotency token implemented, the flow would be this way:
Antes de realizar a operação, meu token de idempotência é gerado com o valor 98s0a9F
1) (Saldo total) R$1000,00
2) Transferência de R$100,00 para minha conta (POST /transfers?amount=100&tk=98s0a9F)
3) 200 OK | (Saldo total) R$900,00
Nova operação, meu token de idempotência é gerado com o valor f019a8f
4) Transferência de R$900,00 para minha conta (POST /transfers?amount=900&tk=f019a8f)
5) CONNECTION TIMEOUT | (Saldo total) ?
6) Transferência de R$900,00 para minha conta (POST /transfers?amount=900&tk=f019a8f)
7) 200 OK | (Saldo total) R$0,00
For this second example, the server will identify that for the token f019a8f
an operation has already been carried out, and will only send the result of the operation that occurred successfully, without carrying out a new transfer.
Right and where I can see this idempotency working?
To Stripe has a very interesting mechanism of idempotency to ensure that no operation is performed without actually having the intention to perform it.
It is also important to note that in the case of HTTP, there are methods that are idempotentes by default and do not require this treatment.
Should such an operation necessarily be an initial value? I mean, if in your example we add a release called
saldo atualizado
, with the value of the modifications, would also be aidempotente
? Example:04/01/2017 35,00 Saldo atual
– Marcelo de Andrade
@Marcelodeandrade yes, if your operation establishes a state (instead of modifying it) it can be considered as idempotent as well.
– OnoSendai