𝗧𝗵𝗲 𝗧𝗿𝗮𝗽 𝗜𝗻 𝗕𝗮𝗰𝗸𝗲𝗻𝗱 𝗧𝘂𝘁𝗼𝗿𝗶𝗮𝗹𝘀
Tutorial menunjukkan proses yang sederhana. Terima webhook. Perbarui database. Kembalikan 200 OK.
Kode Anda berjalan saat pengujian. Anda mendorongnya ke produksi. Kemudian Anda melihat catatan duplikat di database Anda. Pengguna mendapatkan kredit dua kali. Entri data menumpuk.
Tutorial mengabaikan realitas kegagalan jaringan.
Masalahnya: Jaringan yang Tidak Andal Jaringan bisa gagal. Server Anda mungkin memproses data dengan lambat. Kesalahan DNS mungkin menghentikan respons 200 OK Anda untuk sampai ke pengirim.
Ketika sebuah layanan tidak menerima konfirmasi Anda, ia akan melakukan retry. Ia mengirimkan webhook yang sama kembali. Jika kode Anda menerima setiap permintaan, Anda akan membuat duplikat.
Solusinya: Idempotensi Idempotensi berarti melakukan beberapa permintaan identik memiliki efek yang sama dengan satu permintaan tunggal.
Bayangkan tombol lift. Menekan tombol lantai 5 satu kali memberi tahu lift ke mana harus pergi. Menekannya sepuluh kali tidak akan mengirim lift ke lantai 50. Hasilnya tetap sama.
Webhook Anda harus bertindak seperti tombol tersebut.
Cara Memperbaikinya Ikuti langkah-langkah ini untuk membangun webhook yang aman:
- Temukan ID unik dari event tersebut.
- Periksa database Anda untuk ID tersebut sebelum melakukan apa pun.
- Jika ID sudah ada, berhenti. Kembalikan 200 OK agar pengirim berhenti melakukan retry.
- Jika ID baru, proses datanya.
- Simpan ID event ke database Anda segera.
Example Logic in Node.js:
const eventId = req.body.event_id;
const existingEvent = await db.processedEvents.findUnique({
where: { id: eventId }
});
if (existingEvent) {
return res.status(200).send('Already processed');
}
await updateUserData(req.body.data);
await db.processedEvents.create({ data: { id: eventId } });
return res.status(200).send('Success');
Membangun sistem untuk kondisi yang sempurna itu mudah. Membangun sistem untuk menghadapi kegagalan adalah engineering yang sesungguhnya.
Pernahkah Anda menghadapi data duplikat akibat retry? Bagaimana Anda menangani idempotensi?