Learn about idempotency – the key ingredient for reliable APIs
So, the idempotency… What does it even mean and what makes something idempotent? Is it really that important for good architecture?
Adrienne Braganza Tacke, software engineer, and keynote speaker, explains this ‘secret ingredient’ and shares tools to help make your requests, APIs, or functions idempotent.
Explanation of idempotency – in simple words!
Adrienne shares an example: “My husband and I are on a road trip, and I want to order a cake from a bakery in Las Vegas. I lose a network connection in a tunnel right after placing the order. When I regain connection, I resubmit the order, thinking it didn’t go through the first time. Without idempotency, I end up with two cakes, even though my intent was to order only one.”
This is a simple example, but imagine this happening with something more serious – bank transactions or other critical operations.
So, idempotent in tech means that a certain operation can be applied many times, without changing the result. The lack of idempotency means the system cannot capture the true intent of a request, leading to harmful side effects like duplicate charges or withdrawals.
Idempotency is key to mitigating side effects while solving problems
And what does idempotency have to do with good architecture? According to Adrienne, it has everything to do with it.
Have you heard about the seven design principles of well-architected applications? These principles are:
- Speedy,
- Simple,
- Singular (meaning focusing on doing a single thing at a time),
- Sharing nothing, specifically in serverless (assuming no state or information sharing between servers),
- Assuming no hardware affinity,
- Using events to trigger transactions rather than function chaining,
- Thinking about concurrent requests rather than total requests.
And the most important one here, claims Tacke, is designing for failures and duplicates. Without idempotency, says she, this principle is impossible to uphold. “Failure is always going to happen. If we keep that in mind, we develop our applications differently, considering edge cases, error handling, and how to deal with inevitable failures.”
So, failures lead to retries – we’ve been solving problems by trying something again, resending something, or turning it on and off again, knowing that retries are part of our toolbox means we need to understand that duplicates can and will occur.
If we’re the ones implementing retries, we are potentially introducing duplicates into our system. And that’s okay, as long as we handle it properly. This is where idempotency is key to mitigating side effects.
How to apply this in our projects?
Adrienne offers three key elements to apply idempotency: an idempotency key, an idempotency layer, and persistent storage.
- Idempotency Key: This is usually generated by the client and uniquely identifies each request. It could be a unique identifier, a hash of the event, or a timestamp.
- Idempotency Layer: This acts as a filter in the API layer, deciding what to do with the request by checking if the key has been seen before.
- Persistent Storage: This stores the state and acts as the source of truth, allowing the idempotency layer to determine whether the request has been processed.
“Applying these, let’s revisit our bakery example. When I place an order, an idempotency key is generated and sent with the request. The API checks this key against persistent storage. If the key hasn’t been seen before, the order is processed, and the result is stored. If the request is retried, the API sees the key, recognizes it, and prevents duplicate processing, ensuring my intent is honored.”
And if you want to try idempotency, AWS Lambda Power Tools is a great resource. They have implementations for TypeScript, .NET, Python, and Java. This library includes features like preventing multiple executions of the same payload during a time window and handling concurrent executions. It uses persistent storage, like DynamoDB, to track idempotency keys and states, making it easier to debug and manage.
She adds that other tools and libraries include Stripe’s API, which has excellent documentation on implementing idempotency, and the idempotent API library for .NET solutions, which uses idempotent decorators to add idempotency to APIs. Finally, Cisco also has products using idempotent requests.