microservices

What are Idempotent APIs? Examples with GET, PUT, DELETE

What is Idempotency?

An API is idempotent if making the same request multiple times produces the same result as making it once. The server state doesn't change after the first call.

Analogy: Pressing an elevator button 5 times has the same effect as pressing it once — the elevator is still called.

HTTP Methods & Idempotency

MethodIdempotent?Safe?Explanation
GET✅ Yes✅ YesRetrieves data. GET /users/1 always returns the same user (no state change)
PUT✅ Yes❌ NoReplaces a resource. PUT /users/1 {name: "Akash"} — calling 10 times still results in the same user state
DELETE✅ Yes❌ NoDELETE /users/1 — first call deletes, subsequent calls return 404 but server state is unchanged
PATCH❌ Maybe❌ NoDepends on implementation. PATCH /users/1 {age: age+1} is NOT idempotent (increments each time)
POST❌ No❌ NoPOST /orders {item: "phone"} — each call creates a new order

Why Does Idempotency Matter?

In distributed systems, network failures and retries are inevitable:

Client → POST /payments {amount: 5000}     → 200 OK (payment created)
Client → [timeout, no response received]
Client → POST /payments {amount: 5000}     → 200 OK (DUPLICATE payment! ❌)

Without idempotency, the user is charged twice.

Making POST Idempotent: Idempotency Keys

@PostMapping("/payments") public ResponseEntity<Payment> createPayment( @RequestHeader("Idempotency-Key") String idempotencyKey, @RequestBody PaymentRequest request ) { // Check if this key was already processed Optional<Payment> existing = paymentRepo.findByIdempotencyKey(idempotencyKey); if (existing.isPresent()) { return ResponseEntity.ok(existing.get()); // Return cached result } // First time — process the payment Payment payment = paymentService.process(request); payment.setIdempotencyKey(idempotencyKey); paymentRepo.save(payment); return ResponseEntity.status(201).body(payment); }

Client sends a unique key per logical operation:

POST /payments
Idempotency-Key: "txn-abc-123"
{amount: 5000}

PUT vs POST — The Idempotency Difference

// PUT — Idempotent: replaces the ENTIRE resource PUT /users/1 { "name": "Akash", "age": 25 } // Call 1: Sets user to {name: Akash, age: 25} // Call 2: Sets user to {name: Akash, age: 25} ← Same state // POST — NOT Idempotent: creates a NEW resource each time POST /users { "name": "Akash", "age": 25 } // Call 1: Creates user with id=1 // Call 2: Creates user with id=2 ← Different state!

Real-World Examples

ServiceIdempotency Strategy
StripeIdempotency-Key header on all POST requests
RazorpayUnique receipt ID for order creation
AWS SQSMessageDeduplicationId for FIFO queues
KafkaProducer enable.idempotence=true with sequence numbers
What are Idempotent APIs? Examples with GET, PUT, DELETE | DevExCode