Understanding API Idempotency: Concepts, Necessity, and Practical Implementation Strategies
This article uses a relatable story to illustrate a real‑world incident caused by missing API idempotency, explains what idempotency is, why it is essential, which interfaces require it, and presents practical backend and frontend solutions such as unique indexes, optimistic/pessimistic locks, token mechanisms, and distributed locks.
Sharing is the most effective way to learn.
Story
On a pleasant sunny day, a cat developer wearing headphones was peacefully coding when the team lead rushed over with an urgent report: a client from Company A claimed that points were being deducted multiple times.
The cat recalled that the interface had not been modified recently; a few days earlier, an external platform had requested a payment interface, which was provided without changing existing code.
While reviewing old code, the cat realized the problem stemmed from the lack of idempotency in the newly exposed API.
The cat's points‑exchange mall originally used a custom H5 page with built‑in duplicate‑submission protection, but the new client wanted a personalized H5 front‑end and directly integrated the API, which unfortunately did not implement idempotency.
Consequently, data correction and an incident report were unavoidable.
Talk About Idempotency
API Idempotency Overview
This case is a typical example of missing API idempotency, so let’s analyze the concept from several angles.
What Is API Idempotency
Technical definition: executing the operation any number of times yields the same effect as the first execution. Plain language: repeated calls produce a consistent final result.
Why Do We Need Idempotency?
Network fluctuations may cause delayed backend responses, prompting users to click repeatedly and submit duplicate requests.
In distributed systems, retry mechanisms for RPC calls can lead to multiple submissions of the same request.
Message queues may redeliver messages when acknowledgments are lost, causing duplicate processing.
Malicious attacks can exploit poorly designed interfaces to perform repeated submissions, such as automated voting attacks.
Which APIs Need Idempotency?
Not every API requires idempotency, as implementing it consumes system resources. Generally, query interfaces do not need it, and simple delete operations may be exempt depending on the scenario. However, most APIs that involve multi‑table updates should implement idempotency.
Practical Idempotency Solutions
Frontend Debounce Handling
Frontend debouncing can be addressed in two ways:
Technical: limit submission to once per 100 ms per user.
Product: disable the submit button after the first click.
Based on Database Unique Index
Use a unique index to prevent duplicate submissions. For example, store the order transaction number as a unique key in a deduplication table. If an insert fails due to a primary‑key conflict, return a friendly error to the client.
Database Optimistic Lock Implementation
Optimistic locking assumes concurrent transactions rarely interfere. It adds a version column and checks it during updates.
update Account set balance = balance-#{payAmount} where accountCode = #{accountCode}With version control:
update Account set balance = balance-#{payAmount}, version = version + 1 where accountCode = #{accountCode} and version = #{currVersion}Database Pessimistic Lock Implementation
Pessimistic locks use row‑level locking (e.g., SELECT ... FOR UPDATE) to serialize access. The following flow demonstrates handling an order with a pessimistic lock.
begin; # 1. Start transaction
select * from order where order_code='666' for update # Lock the row
if (status != 'processing') {
// Non‑processing status, return immediately
return;
}
# Business logic processing
update order set status='completed' where order_code='666';
update stock set num = num - 1 where spu='xxx';
commit; # 5. Commit transactionBackend‑Generated Token
This approach introduces a token bucket mechanism. The frontend first requests a token from the backend; the token is stored in Redis with an expiration time.
When the order submission arrives, the backend checks the token's existence. The first request succeeds; subsequent requests with the same token are rejected.
If a malicious program repeatedly uses the same token, a distributed lock combined with a Lua script is needed to ensure atomicity of token validation, order number generation, and token deletion.
Distributed Lock + State Machine (Order Status)
Many services run in distributed environments. For distributed locking, refer to the following articles:
Evolution of Locks
Hand‑crafted Redis Distributed Lock
Hand‑crafted ZK Lock
Similar to the pessimistic‑lock example, a distributed lock ensures that the same order is processed only once at a time, and the order status must be checked to prevent duplicate payments.
Summary
In daily development, critical interfaces—especially those involving financial transactions—must be handled with care. Even if an interface has not been modified since its predecessor, it should be reviewed for potential idempotency issues.
Idempotency is crucial for reliable systems; feel free to share your own solutions or thoughts in the comments.
I'm Lao Cat, a senior R&D veteran. Let’s discuss technology and life together.
If you enjoyed this article, please give it a like, follow, and a three‑click boost. Thank you for your support.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
