Cara Idempotency Membantu API Menangani Request yang Sama Berulang Kali

-

Kamu pasti pernah menggunakan aplikasi atau website yang berinteraksi dengan API, kan? Contohnya seperti melakukan pembelian barang, kirim pesan, atau bahkan login. Nah, kadang-kadang kita bisa saja mengalami situasi di mana permintaan (request) yang kita kirimkan ke API itu terkirim lebih dari sekali, entah karena jaringan yang terputus atau pengguna yang tidak sadar mengklik tombol berkali-kali. Di sinilah konsep idempotency memainkan peran penting.

Jadi, apa itu idempotency dan bagaimana ia membantu API menangani permintaan yang sama berulang kali? Yuk, kita bahas lebih dalam!

Apa Itu Idempotency?

Idempotency adalah sebuah konsep dalam dunia API yang memastikan bahwa tidak peduli berapa kali kamu mengirimkan request yang sama, hasilnya akan selalu sama. Jadi, meskipun kamu menekan tombol "Kirim" berkali-kali, hanya akan ada satu tindakan yang terjadi di server. Tidak ada penggandaan atau kesalahan lainnya.

Misalnya, kamu sedang membeli tiket konser online dan terjadi error saat pembayaran. Kamu tidak sengaja mengklik tombol “Bayar” beberapa kali. Tanpa idempotency, API bisa jadi akan memproses pembayaran itu lebih dari sekali, padahal kamu hanya ingin satu tiket.

Nah, idempotency ini memastikan bahwa meski kamu mengklik tombol tersebut beberapa kali, hanya satu pembayaran yang akan diproses.

Kenapa Idempotency Penting dalam API?

Buat kamu yang bekerja dengan API, kamu pasti ingin memastikan bahwa request yang dikirimkan ke server tidak menimbulkan efek samping yang tidak diinginkan. Dengan idempotency, kamu bisa mencegah masalah seperti:

  1. Duplikasi Transaksi: Sebagai contoh, transaksi yang sama tidak akan diproses lebih dari satu kali, yang bisa menyebabkan kamu dibebani pembayaran ganda.

  2. Konsistensi Data: Dengan idempotency, data yang dikirimkan tidak akan berlipat ganda. Misalnya, jika kamu menambah produk ke keranjang belanja, produk itu tidak akan ditambahkan berulang kali meski kamu mengklik beberapa kali.

  3. Pengalaman Pengguna yang Lebih Baik: Pengguna tidak perlu khawatir request yang mereka kirim akan menyebabkan masalah atau data yang berantakan. Ini membuat aplikasi lebih stabil dan mengurangi potensi frustrasi.

Bagaimana Idempotency Bekerja?

Idempotency bekerja dengan cara menggunakan idempotency key. Ini adalah sebuah kode unik yang dihasilkan saat kamu mengirimkan request pertama kali. API kemudian menggunakan kode ini untuk mengenali apakah request yang kamu kirim adalah request yang sudah pernah diproses sebelumnya. Jika request yang sama dikirimkan lagi, server akan mengenali idempotency key yang sama dan hanya akan memproses request tersebut sekali.

Misalnya, kamu sedang melakukan pembayaran di e-commerce. Saat kamu mengklik “Bayar”, server akan mengirimkan idempotency key yang unik ke aplikasi. Jika kamu mengklik "Bayar" lagi, API akan mengenali idempotency key tersebut dan tidak akan memproses transaksi ganda.

Contoh Kasus Penggunaan Idempotency

Misalkan kamu membeli produk di sebuah toko online. Berikut adalah cara idempotency bekerja di balik layar:

  1. Request Pertama:

    • Kamu klik tombol "Bayar Sekarang".
    • Server menerima request.
    • Pembayaran diproses dan kamu menerima konfirmasi pembelian.
  2. Request Kedua (Misalnya karena klik berulang atau koneksi terputus):

    • Kamu klik tombol "Bayar Sekarang" lagi.
    • Server melihat request sebelumnya yang sama dan tidak memproses ulang pembayaran.
    • Kamu tetap menerima satu konfirmasi pembelian.

Dengan cara ini, meskipun ada masalah jaringan atau kesalahan klik dari user, API tidak akan memprosesnya secara berulang yang bisa menyebabkan kebingungan atau masalah lain.

Contoh Simple Alur

  1. Beli Produk: Setiap kali user melakukan request yang mengubah data (misalnya pembelian), data produk tersebut akan di kirim ke server oleh frontend.
  2. Menyimpan Data Produk: Simpan data produk yang diterima tadi misalnya id pada database atau cache agar bisa digunakan untuk pengecekan pada request berikutnya.
  3. Cek dan Proses Request: Ketika request dengan produk  yang sama datang lagi, server akan memeriksa apakah request tersebut sudah pernah diproses. Jika sudah, maka server tidak akan memproses ulang.

Contoh Implementasi Backend (Laravel):

Pada sisi server, kita akan menggunakan id untuk memeriksa apakah request sudah diproses.

public function processPayment(Request $request) { $id= $request->id; // Menerima id yang dikirim oleh frontend // Cek apakah id sudah ada di database $payment = Payment::where('id', $id)->first(); if ($payment) { return response()->json(['message' => 'Payment already processed'], 200); } // Proses pembayaran jika request_id belum diproses $payment = new Payment(); $payment->amount = $request->amount; $payment->id= $id; $payment->status = 'success'; $payment->save(); return response()->json(['message' => 'Payment processed successfully'], 201); }

Mengatasi Request Berulang di Frontend:

Pada sisi frontend, kita juga perlu mencegah user mengirimkan request yang sama lebih dari sekali (misalnya karena koneksi terputus atau user mengklik tombol berkali-kali karena internet lambat yang menyebabkan seolah-olah server kita tidak merespon).

Untuk itu, kita bisa disable buttonsaat request sedang diproses. Ini akan memastikan bahwa user tidak bisa mengklik button yang sama hingga proses selesai.

Contoh Kode di Frontend (React):

import { useState } from 'react'; import axios from 'axios'; const PaymentForm = () => { const [isProcessing, setIsProcessing] = useState(false); const handlePayment = async () => { if (isProcessing) return; // Menghindari request berulang saat button sudah dinonaktifkan setIsProcessing(true); // Menandakan pembayaran sedang diproses try { await axios.post('/api/process-payment', { amount: 100 }); alert('Payment processed successfully'); } catch { alert('Payment failed. Please try again.'); } finally { setIsProcessing(false); // button diaktifkan kembali } }; return ( <button onClick={handlePayment} disabled={isProcessing}> {isProcessing ? 'Processing...' : 'Pay Now'} </button> ); }; export default PaymentForm;

Penjelasan:

  • isProcessing: State yang digunakan untuk mengecek apakah request sedang diproses atau tidak.
  • handlePayment: Fungsi untuk menangani pengiriman pembayaran. Fungsi ini hanya akan dijalankan jika request belum diproses (isProcessing masih false).
  • Button: Tombol akan dinonaktifkan (disabled={isProcessing}) selama pembayaran diproses, dan akan berubah teks menjadi "Processing..." untuk memberi tahu user bahwa transaksi sedang diproses.
  • setIsProcessing(true): Button dinonaktifkan saat request dimulai.
  • setIsProcessing(false): Button akan diaktifkan kembali setelah request selesai diproses, baik berhasil maupun gagal.

Dengan cara ini, meskipun user mengklik tombol beberapa kali, hanya request pertama yang akan diproses, dan tombol akan tetap dinonaktifkan hingga request selesai.

Kapan Idempotency Tidak Digunakan?

Idempotency sangat berguna untuk request yang berpengaruh pada data atau transaksi finansial. Tapi, untuk request yang tidak berisiko menyebabkan perubahan yang berulang, seperti request informasi yang tidak mengubah status server (misalnya, hanya menampilkan data), idempotency mungkin tidak diperlukan.

Contoh lainnya adalah permintaan GET atau lihat data yang tidak akan mengubah apa pun di server. Contoh lain misal ingin request untuk menampilkan profil user tidak akan memerlukan idempotency, karena hanya mengambil data dan tidak menyebabkan perubahan apapun di server.

Kesimpulan

Idempotency adalah konsep yang sangat penting bagi developer API untuk memastikan aplikasi yang dibuat berjalan mulus meski terjadi kesalahan teknis atau user mengirimkan request yang sama berulang kali. Dengan menggunakan idempotency, API tidak akan memproses berkali-kali yang bisa merusak data atau transaksi.

Jadi, dengan menerapkan idempotency dalam aplikasi atau API yang sedang dikembangkan, kamu bisa memastikan experience user yang lebih baik, transaksi yang lebih aman, dan aplikasi yang lebih stabil.