Idempotency keys help make sure that when you send the same request multiple times, it only happens once. This stops mistakes like double payments or duplicate orders.
Idempotency keys for safe retries in Rest API
POST /api/orders HTTP/1.1 Idempotency-Key: unique-key-123 Content-Type: application/json { "item": "book", "quantity": 1 }
The Idempotency-Key is a unique string sent in the request header.
The server uses this key to remember the request and avoid doing the same action twice.
POST /api/payments HTTP/1.1 Idempotency-Key: abc123 Content-Type: application/json { "amount": 100 }
POST /api/payments HTTP/1.1 Idempotency-Key: abc123 Content-Type: application/json { "amount": 100 }
POST /api/orders HTTP/1.1 Content-Type: application/json { "item": "pen", "quantity": 2 }
This program creates a simple API that accepts orders with an Idempotency-Key header.
If the same key is sent again, it returns the saved response instead of creating a new order.
from flask import Flask, request, jsonify app = Flask(__name__) # Store processed idempotency keys and their responses processed_requests = {} @app.route('/api/orders', methods=['POST']) def create_order(): idempotency_key = request.headers.get('Idempotency-Key') if not idempotency_key: return jsonify({'error': 'Idempotency-Key header missing'}), 400 if idempotency_key in processed_requests: # Return the previous response to avoid duplicate processing return jsonify(processed_requests[idempotency_key]) data = request.get_json() item = data.get('item') quantity = data.get('quantity') # Simulate order creation order_id = len(processed_requests) + 1 response = { 'order_id': order_id, 'item': item, 'quantity': quantity, 'status': 'created' } # Save response with idempotency key processed_requests[idempotency_key] = response return jsonify(response) if __name__ == '__main__': app.run(debug=True)
Time complexity: Checking and storing keys is usually O(1) with a hash map.
Space complexity: Stores keys and responses, so memory grows with unique requests.
Common mistake: Forgetting to require or check the Idempotency-Key header, which defeats the purpose.
Use idempotency keys when you want safe retries; use other methods like transactions for different guarantees.
Idempotency keys prevent duplicate actions by making repeated requests safe.
They work by sending a unique key with each request that the server remembers.
This is very useful for payments, orders, and any action that should happen only once.
Practice
idempotency key in REST APIs?Solution
Step 1: Understand idempotency key concept
An idempotency key is a unique identifier sent with a request to ensure the server processes it only once.Step 2: Identify the main purpose
This prevents duplicate actions like double payments or repeated orders if the client retries the request.Final Answer:
To prevent duplicate processing of the same request -> Option BQuick Check:
Idempotency key = prevent duplicates [OK]
- Confusing idempotency key with authentication token
- Thinking it speeds up response time
- Assuming it encrypts data
Solution
Step 1: Recall standard header for idempotency
The standard practice is to send the unique idempotency key in theIdempotency-KeyHTTP header.Step 2: Differentiate from other headers
Authorizationis for credentials,Content-Typedefines data format, andCache-Controlmanages caching.Final Answer:
Idempotency-Key -> Option AQuick Check:
Idempotency key header = Idempotency-Key [OK]
- Using Authorization header for idempotency key
- Confusing Content-Type with idempotency key
- Sending key in request body instead of header
stored_keys = {}
def handle_request(idempotency_key, data):
if idempotency_key in stored_keys:
return stored_keys[idempotency_key]
response = process_data(data)
stored_keys[idempotency_key] = response
return response
# Client sends:
print(handle_request('abc123', 'order1'))
print(handle_request('abc123', 'order1'))
print(handle_request('xyz789', 'order2'))
What will be the output?Solution
Step 1: Analyze first call with key 'abc123'
Key not in stored_keys, so process_data('order1') runs, result saved and returned.Step 2: Analyze second call with same key 'abc123'
Key found, stored response returned without reprocessing.Step 3: Analyze third call with new key 'xyz789'
Key not found, process_data('order2') runs, result saved and returned.Final Answer:
process_data output for order1, process_data output for order1, process_data output for order2 -> Option DQuick Check:
Repeated key returns cached response [OK]
- Assuming second call reprocesses data
- Confusing keys and responses
- Thinking None is returned on repeats
cache = {}
def post_request(key, data):
if key not in cache:
process(data)
return cache[key]
What is the bug in this code?Solution
Step 1: Check caching logic
The code checks if key not in cache, then calls process(data), but never saves the result in cache.Step 2: Identify consequence
Since cache[key] is never set, returning cache[key] will cause a KeyError or return None incorrectly.Final Answer:
It never stores the processed result in cache -> Option AQuick Check:
Missing cache storage causes errors [OK]
- Assuming process(data) stores result automatically
- Ignoring missing cache assignment
- Thinking HTTP method affects caching here
Solution
Step 1: Understand safe retry requirements
Safe retries mean the client can resend the same request without causing duplicate charges.Step 2: Evaluate options
Store the payment result linked to the idempotency key and return it on repeated requests stores the payment result linked to the key and returns it on repeats, preventing double charges. Ignore the idempotency key and process every request independently processes every request, risking duplicates. Reject any request with an idempotency key that was seen before rejects repeats, which may cause client errors. Process the payment again but log a warning for duplicate keys processes again, causing duplicates.Final Answer:
Store the payment result linked to the idempotency key and return it on repeated requests -> Option CQuick Check:
Store and reuse result for idempotency [OK]
- Rejecting repeated keys causing client errors
- Processing duplicates causing double charges
- Logging warnings but still charging twice
Ready to prove it?
Pass the test and this pattern moves unknown
