Pendahuluan ke Kontrak API Webhook Idempoten
Untuk memastikan retry aman, kontrak API webhook harus mendefinisikan bagaimana payload dan header diproses agar setiap pengiriman ulang tidak menimbulkan efek samping ganda. Dengan spesifikasi idempoten yang jelas, penerima dapat membedakan permintaan baru dari yang sudah diproses, sehingga operasi seperti transaksi atau perubahan status tidak terduplikasi.
Dalam pendekatan ini, fokus utama adalah validasi payload, autentikasi header, mekanisme deteksi replay, pemetaan status (state map), serta observabilitas. Dengan kombinasi tersebut, sistem dapat menangani kegagalan yang mengakibatkan retry tanpa mengorbankan konsistensi.
Validasi Payload dan Header Autentikasi
Kontrak harus menetapkan format payload minimal dan aturan validasi yang deterministik. Payload yang tidak lengkap atau tidak sesuai skema harus ditolak secara eksplisit agar pengirim tahu bahwa tidak perlu retry yang sama.
Contoh JSON Schema sederhana di bawah bisa menjadi dasar validasi payload:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["eventId", "eventType", "data"],
"properties": {
"eventId": {
"type": "string",
"pattern": "^[A-Za-z0-9\-_.]+$"
},
"eventType": {
"type": "string"
},
"data": {
"type": "object"
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
}Kode di atas menegaskan bahwa setiap event memiliki eventId unik, dan validator harus menolak payload di luar skema. Autentikasi header, seperti menggunakan HMAC atau token, memastikan payload tidak diubah di perjalanan. Header seperti X-Signature atau Authorization harus diperiksa terhadap rahasia bersama dan waktu kedaluwarsa, dan respon 401/403 harus dikembalikan jika invalid.
Deteksi Replay dan State Map
Untuk idempoten, layanan penerima harus menyimpan state map sederhana dengan kunci utama eventId. Ketika webhook diterima:
- Validasi payload dan header selesai.
- Periksa apakah
eventIdsudah ada di cache atau database (misalnya Redis dengan TTL sesuai SLA). - Jika belum, proses event dan simpan status (berhasil/gagal) di state map.
- Jika sudah diproses, kembalikan status yang konsisten tanpa memproses ulang.
Penyimpanan status bisa berupa struktur seperti {eventId: {status: "succeeded", updatedAt: "...", resultHash: "..."}}. Dengan menyimpan hash dari hasil, sistem bisa memverifikasi konsistensi ketika retry dikirimkan dengan payload serupa.
Penanganan Penerima Gagal Idempoten
Ketika penerima gagal idempoten (misalnya karena timeout di sisi webhook sender), diagram alirnya:
- Webhook sender mengirim ulang karena tidak menerima 2xx dalam batas waktu.
- Penerima menerima ulang, memeriksa state map berdasarkan
eventId. - Jika status terakhir
processingataufailed, sistem dapat: - Mengecek apakah retry dapat diulang (misal: transaksi belum selesai dan tidak ada efek samping).
- Menolak dengan 409 dan menyertakan payload status saat ini.
- Menjawab 200 dan mengembalikan data hasil sebelumnya jika idempoten sudah sukses.
Strategi ini mencegah penerima memproses tindakan yang sama dua kali dan memberi informasi kepada pengirim agar tidak lanjut retry jika tidak perlu.
Observabilitas dalam Kontrak Webhook
Observabilitas adalah kunci untuk memahami bagaimana retry memengaruhi sistem.
- Log: Catat
eventId, hasil validasi, status state map, serta alasan kegagalan (misalnya validasi schema atau signature mismatch). - Tracing: Hubungkan setiap webhook dengan trace ID untuk melacak operasional lintas layanan.
- Metrics: Hitung rasio retry, interval antara retry, dan jumlah event yang diidentifikasi sebagai duplikat agar dapat mengevaluasi tuning TTL atau ukuran cache.
Observabilitas membantu memutuskan kapan menyesuaikan waktu tunggu retry, menambah kapasitas sistem penerima, atau melakukan perbaikan kontrak.
Debugging Retry dan Duplikasi
Masalah umum adalah retry menyebabkan duplicate effect karena state map tidak tersebar luas atau pemrosesan asinkron tidak sinkron.
Langkah-langkah debugging:
- Verifikasi header autentikasi dan timestamp untuk memastikan tidak ada replay attack yang valid.
- Periksa cache state map. Jika status
succeededtetapi operasi tetap dijalankan ulang, pastikan logika pemrosesan memeriksa status sebelum menjalankan tindakan sisi bisnis. - Lacak sequence log berisi
eventIddan payload hash untuk melihat apakah payload berubah di antara retry. - Jika duplikasi terjadi saat proses duplikat diterima, tambahkan kunci distribusi (seperti locking berdasarkan
eventId) untuk menghindari race condition.
Jika sistem menerima webhook lewat antrian (misalnya queue atau Kafka), pastikan contract menjelaskan bahwa order tidak dijamin, sehingga state map harus tahan terhadap pesan yang datang tidak berurutan.
Kesimpulan
Kontrak API webhook yang mendukung idempoten dan retry aman harus menjelaskan validasi payload, header autentikasi, deteksi replay, pemetaan status, serta observabilitas. Dengan mengikuti pola ini, tim dapat menyusun dokumentasi webhook yang menjamin setiap event diproses tepat sekali walau terjadi retry. Penggunaan state map, log detail, dan struktur penanganan kegagalan memperkecil risiko duplikasi saat sistem dihadapkan pada jaringan tidak stabil atau kegagalan transient.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!