Idempotency in REST APIs — Complete Guide
In this tutorial, you will learn about Idempotency in REST APIs. We cover key concepts, practical examples, and best practices to help you master this topic.
Idempotency in REST APIs means making the same request multiple times produces the same result as making it once, preventing duplicate side effects and ensuring reliable communication over unreliable networks.
flowchart TD A[Client] -->|Same Request x3| B[Server] B -->|Same Response x3| A A -->|POST Without Key| C[Server] C -->|3 Resources Created| A A -->|POST With Key| D[Server] D -->|Same Resource Returned| A style A fill:#e1f5fe style B fill:#c8e6c9 style D fill:#c8e6c9 style C fill:#ffcdd2
An idempotent operation guarantees that calling it once or multiple times has the same effect. GET is idempotent: reading the same resource 100 times returns the same data. PUT is idempotent: replacing a resource with the same data does the same thing each time. DELETE is idempotent: deleting a resource that already does not exist changes nothing.
POST is not idempotent. If you POST the same order twice, the customer gets charged twice. This is why payment systems use idempotency keys. A client generates a unique key for each request. If the request fails due to a network error, the client retries with the same key, and the server recognizes it as a duplicate.
Think of idempotency keys like a hotel reservation confirmation number. If you call the hotel to confirm and the call drops, you call back with the same confirmation number. The hotel knows you already booked and does not create a duplicate reservation.
Example: Idempotent GET
import requests
# Calling GET 3 times produces the same result
for i in range(3):
response = requests.get("https://api.example.com/users/42")
print(f"Attempt {i+1}: {response.json()['name']}")
Expected output:
Attempt 1: Alice
Attempt 2: Alice
Attempt 3: Alice
Example: Non-Idempotent POST Without Idempotency Key
import requests
data = {"name": "Test", "email": "test@example.com"}
for i in range(3):
response = requests.post("https://api.example.com/users", json=data)
print(f"Attempt {i+1}: Created user {response.json()['id']}")
Expected output:
Attempt 1: Created user 101
Attempt 2: Created user 102
Attempt 3: Created user 103
Example: POST With Idempotency Key
import requests
import uuid
data = {"amount": 5000, "currency": "USD"}
idempotency_key = str(uuid.uuid4())
headers = {"Idempotency-Key": idempotency_key}
for i in range(3):
response = requests.post(
"https://api.example.com/payments",
json=data,
headers=headers
)
print(f"Attempt {i+1}: {response.json()['status']}")
Expected output:
Attempt 1: completed
Attempt 2: completed (duplicate, returned cached)
Attempt 3: completed (duplicate, returned cached)
Common Mistakes
- Assuming all POST requests are idempotent — Most POST requests are not idempotent. Only operations like POST to a search endpoint might be idempotent.
- Not implementing idempotency keys for critical operations — Payment processing, order creation, and account registration must use idempotency keys.
- Expiring idempotency keys too quickly — Keys should live long enough to cover retry Windows, typically 24 hours for payment operations.
- Ignoring idempotency in Distributed Systems — When multiple API instances Process requests, idempotency checks must use a shared store like Redis.
- Returning different response bodies for duplicate requests — An idempotent request should return the same response each time, not just prevent side effects.
Practice Questions
- Which HTTP methods are idempotent?
- Why is POST not idempotent?
- What is an idempotency key used for?
- How would you implement idempotency for a payment API?
- Challenge: Implement an idempotency middleware in Python that stores idempotency keys in a dictionary and returns cached responses for duplicate requests.
FAQ
Mini Project
Build a Python class that wraps a payment API with idempotency support. The class should generate unique idempotency keys, store responses for completed requests, and return cached responses for retries. Test with simulated network failures.
What's Next
Now learn about HTTP status codes in REST API Design.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro