Strategi kontrak API webhook harus memberikan kepastian kepada pengirim maupun penerima bahwa setiap notifikasi ditangani satu kali dan dapat diulang tanpa merusak keadaan sistem. Dalam kontrak ini, kita menetapkan skema backoff retry eksplisit, cara verifikasi payload melalui token dan signature, serta mekanisme idempotensi yang ditulis ke dalam status webhook untuk menghindari efek samping saat terjadi kegagalan.
Dengan pendekatan ini, sudah sejak awal jelas bagaimana header dan body ditetapkan, bagaimana status webhook bergerak dari pending ke success atau retry, serta bagaimana handler memeriksa ulang idempotensi dan mencatat hasil. Seluruh detail ini menjaga agar webhook tetap aman, terukur, dan mudah dipantau.
Rancang Kontrak Webhook yang Eksplisit
Kontrak harus mendokumentasikan header yang akan dikirim, struktur payload, tipe status, serta metadata retry. Contoh header/body minimal:
POST /webhook/handlers/order-status HTTP/1.1
Host: api.penerima-sumber.com
Content-Type: application/json
X-Webhook-Id: 6f9e97a1
X-Webhook-Signature: sha256=abcdef...
X-Webhook-Retry: 2
{
"event": "order.completed",
"timestamp": "2024-10-05T14:32:00Z",
"order_id": "ORD-123",
"payload": {
"total": 259900,
"currency": "IDR"
}
}
Pastikan kontrak mencatat:
- X-Webhook-Id unik untuk setiap event, dipakai untuk idempotensi.
- X-Webhook-Signature menghitung HMAC atas body menggunakan shared secret.
- X-Webhook-Retry opsi tambahan untuk menyertakan nomor percobaan, memudahkan logging.
Status webhook harus mengikuti pola: received → processing → success atau retry/failed. Dokumen kontrak juga menyebutkan timeout maksimum yang diperbolehkan di sisi penerima agar pengirim tidak menunggu terlalu lama.
Backoff Retry
Setiap retry harus didorong oleh pola backoff yang dibahas dalam kontrak. Jangan hanya mengandalkan retry otomatis tanpa jeda karena bisa memberatkan sistem penerima. Contohnya, kontrak bisa menyarankan backoff eksponensial terbatas:
- Delay awal 1s:
1000ms - Naik 2x setiap retry hingga maksimum 32s
- Batasi jumlah retry (misal 5) sebelum status masuk
failed
Bagian pentingnya adalah menyimpan waktu next_attempt_at di metadata dan menginformasikan status ke dashboard agar operator tahu pesan mana yang sedang menunggu retry.
Untuk memudahkan debugging, kontrak juga bisa mencakup header tambahan seperti X-Webhook-Last-Status dan X-Webhook-Last-Error agar penerima dapat memberi tahu kembali ke pengirim alasan kegagalan jika tersedia.
Idempotensi dan Penyimpanan Status
Ketika webhook diterima berulang kali, handler harus memeriksa apakah event tersebut sudah diproses. Kontrak menekankan penyimpanan status per X-Webhook-Id di basis data yang mendukung atomicity, misalnya menggunakan row-level lock atau upsert untuk menghindari race condition.
Pseudocode handler untuk idempotensi, penyimpanan status, dan backoff:
function handleWebhook(request):
id = request.headers['X-Webhook-Id']
job = db.findOrCreateWebhookJob(id)
if job.status == 'success':
return respond(200, 'Already processed')
if job.status == 'processing' and withinLockWindow(job):
return respond(202, 'Another worker is processing')
job.status = 'processing'
job.attempts += 1
job.last_attempt_at = now()
job.save()
try:
processPayload(request.json)
job.status = 'success'
job.completed_at = now()
job.save()
return respond(200, 'OK')
except TransientError as err:
job.status = 'retry'
job.next_attempt_at = now() + backoff(job.attempts)
job.error_message = err.message
job.save()
return respond(503, 'Retry scheduled')
except PermanentError as err:
job.status = 'failed'
job.error_message = err.message
job.save()
return respond(400, 'Permanent failure')
Pastikan backoff menggunakan rumus eksponensial dengan batas atas agar tidak memicu beban berlebih. Pemrosesan payload harus dilengkapi dengan lock logis, misalnya memanfaatkan kolom processing_token dan timeout lock untuk mencegah race condition.
Verifikasi Payload
Verifikasi memastikan bahwa webhook tidak dimodifikasi. Dalam kontrak, definisikan:
- Algoritme signature: misalnya HMAC-SHA256 dengan shared secret.
- Header signature yang wajib diproses.
- Jam kedaluwarsa pesan untuk mencegah replay attack.
Contoh dokumen kontrak:
- Shared Secret: tidak pernah dikirim lewat webhook. Distributor menyimpan rahasia dari sistem penerima.
- Header:
X-Webhook-Signatureberformatsha256=. - Verifikasi: penerima menghitung HMAC atas body dan membandingkan dengan nilai header sebelum lanjut memroses.
Jika signature gagal, segera respon 401 Unauthorized dan log peristiwa untuk audit. Dokumentasikan langkah penggantian secret dan rotasi keys agar tim operasi dapat merespons insiden dengan cepat.
Mencegah Race Condition dan Timeout Layanan Downstream
Race condition muncul saat beberapa worker memproses webhook sama sekali. Atasi dengan:
- Locks di database menggunakan
SELECT FOR UPDATEatau mekanisme distributed lock dengan TTL. - Kolom
processing_tokenyang menyimpan ID worker aktif dan timestamp. - Timeout pemrosesan yang memicu rollback jika berhasil memproses tapi tidak sempat update status.
Untuk menangani timeout layanan downstream, kontrak menjelaskan batas waktu (misalnya 3 detik) per HTTP request. Jika layanan downstream melebihi, handler harus menganggapnya sebagai TransientError agar job masuk status retry dengan backoff. Dalam log, rekam downstream_endpoint, latency, dan respons terakhir untuk diagnosa.
Monitoring Kegagalan dan Duplikat
Monitoring memberikan visibilitas atas event webhook yang bermasalah:
- Grafik jumlah webhook per status (
pending,retry,failed). - Peringatan saat retry count melewati ambang tertentu dalam window waktu.
- Log detail duplikat yang tertangani untuk memastikan idempotensi berjalan.
Gunakan metrik seperti webhook_processing_duration dan webhook_failure_rate, serta integrasi ke sistem monitoring agar alert muncul saat webhook menumpuk. Simpan log signature verification failure untuk audit keamanan.
Kesimpulan
Kontrak API webhook yang tangguh menggabungkan dokumentasi header/body, pola status yang jelas, strategi backoff, verifikasi signature, dan idempotensi berbasis status yang disimpan. Tambahkan praktik pencegahan race condition, penanganan timeout downstream, serta monitoring kegagalan dan duplikat untuk menjamin reliability. Dengan pendekatan ini, integrasi webhook tetap aman dan dapat diandalkan dalam kondisi nyata.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!