Idempotency #
Dalam pengembangan sistem modern—terutama backend, microservices, dan distributed systems—idempotency adalah salah satu konsep fundamental yang sering disebut, namun kerap disalahpahami atau bahkan diabaikan. Padahal, kegagalan memahami idempotency dapat menyebabkan data corruption, double charging, race condition, dan bug yang sulit direproduksi.
Artikel ini akan membahas idempotency secara mendalam: mulai dari definisi, alasan keberadaannya, contoh konkret, hingga praktik terbaik dalam implementasi.
Apa Itu Idempotency? #
Secara sederhana:
Idempotency adalah sifat suatu operasi yang jika dijalankan berkali-kali dengan input yang sama, akan menghasilkan efek yang sama seperti dijalankan satu kali.
Dalam konteks software engineering, terutama API dan sistem terdistribusi:
- Request yang sama dikirim 1x atau 100x
- Sistem tetap berada pada state akhir yang sama
- Tidak ada efek samping tambahan (side effects)
Definisi Formal #
Sebuah operasi disebut idempotent jika:
f(x) = f(f(x))
Artinya:
- Menjalankan operasi tersebut berulang kali tidak mengubah hasil akhir
Contoh Sederhana #
Contoh Idempotent #
PUT /users/123
{
"name": "Andi"
}
- Dipanggil 1x → nama = Andi
- Dipanggil 10x → nama tetap = Andi
➡️ Idempotent
Contoh Tidak Idempotent #
POST /users/123/balance/add
{
"amount": 100
}
- Dipanggil 1x → saldo +100
- Dipanggil 2x → saldo +200
➡️ Tidak idempotent
Idempotency dalam HTTP Method #
HTTP secara desain sudah mengklasifikasikan method berdasarkan idempotency:
| HTTP Method | Idempotent | Keterangan |
|---|---|---|
| GET | ✅ Ya | Hanya membaca data |
| PUT | ✅ Ya | Mengganti resource secara penuh |
| DELETE | ✅ Ya | Menghapus resource |
| HEAD | ✅ Ya | Metadata saja |
| POST | ❌ Tidak | Biasanya membuat resource baru |
| PATCH | ❌ (biasanya) | Update parsial, tergantung implementasi |
⚠️ Catatan penting: Status idempotent bukan ditentukan oleh method saja, tetapi oleh implementasinya.
Kenapa Penting? #
Dunia Nyata Tidak Ideal #
Dalam sistem nyata:
- Network timeout
- Client retry request
- Load balancer retry
- Message queue redelivery
- Mobile app resend request karena koneksi buruk
Tanpa idempotency:
- Satu aksi user → dieksekusi berkali-kali
- Double payment
- Double order
- Double notification
Retry adalah Keniscayaan #
Di distributed system:
Retry bukan pilihan, tapi kewajiban
Dan setiap retry harus aman.
Idempotency memungkinkan:
- Retry tanpa takut efek samping
- At-least-once delivery
- Event-driven architecture yang stabil
Idempotency vs Duplicate Request #
Idempotency bukan berarti request tidak diulang, tetapi:
Jika request diulang, hasilnya tetap aman.
Perbedaan penting:
| Konsep | Fokus |
|---|---|
| Deduplication | Mencegah request ganda |
| Idempotency | Membuat request ganda tetap aman |
Idempotency Key #
Salah satu teknik paling umum adalah Idempotency Key.
Cara Kerja #
- Client mengirim header:
Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000
Server:
Menyimpan key + hasil operasi
Jika key yang sama datang lagi:
- Tidak mengeksekusi ulang
- Mengembalikan response sebelumnya
Contoh Flow #
Client → POST /payments (key=A)
Server → proses pembayaran → SUCCESS
Client retry → POST /payments (key=A)
Server → key sudah ada → return SUCCESS lama
➡️ Tidak ada double charge
Implementasi Idempotency #
Database-Based #
- Simpan
idempotency_keydi tabel - Tambahkan unique constraint
- Jika duplicate → return existing result
UNIQUE (idempotency_key)
Cache-Based (Redis) #
- Key → response
- TTL tertentu
- Cocok untuk high throughput
Message Queue #
Gunakan:
- Deduplication ID
- Exactly-once simulation
Consumer harus idempotent
Event-Driven Architecture #
Dalam sistem event:
Producer → Queue → Consumer
Masalah:
- Event bisa dikirim ulang
- Consumer bisa crash di tengah proses
Solusi:
- Simpan
event_id - Jika event_id sudah diproses → skip
➡️ Consumer harus idempotent by design
Idempotency ≠ Transaction #
Perbedaan penting:
| Transaction | Idempotency |
|---|---|
| Atomicity | Consistency across retries |
| Rollback | Safe re-execution |
| Scope DB | Scope sistem |
Idempotency sering melengkapi transaction, bukan menggantikannya.
Kesalahan Umum Engineer #
- ❌ Menganggap POST pasti tidak idempotent
- ❌ Mengandalkan client untuk tidak retry
- ❌ Tidak menyimpan state idempotency
- ❌ Consumer queue tidak idempotent
- ❌ Mengira load balancer tidak retry request
Best Practices #
- ✅ Anggap semua request bisa diulang
- ✅ Buat write-operation idempotent
- ✅ Gunakan idempotency key untuk operasi kritikal
- ✅ Consumer event harus idempotent
- ✅ Dokumentasikan behavior idempotency di API
Penutup #
Idempotency bukan konsep akademis, melainkan fondasi stabilitas sistem modern.
Jika sistem Anda:
- Menggunakan retry
- Menggunakan queue
- Menggunakan microservices
- Menghadapi network yang tidak reliabel
Maka:
Idempotency bukan opsional, tapi keharusan.
Engineer yang memahami idempotency dengan baik akan membangun sistem yang:
- Lebih tahan error
- Lebih mudah diskalakan
- Lebih aman secara bisnis