Koneksi yang terputus dapat membuat Anda tidak yakin apakah permintaan pengiriman berhasil. Acknowledgment yang hilang juga dapat menyebabkan pengirim webhook mengirimkan event yang sudah disimpan aplikasi Anda.
Kegagalan ini terjadi dari arah yang berlawanan. Bird dapat mengenali permintaan API yang diulang menggunakan kunci yang Anda berikan. Penerima webhook Anda memerlukan catatannya sendiri tentang event yang sudah diterima.
Bagaimana cara melakukan coba lagi pengiriman dengan aman?
Gunakan kembali Idempotency-Key yang sama dan permintaan yang identik untuk setiap percobaan ulang. Jaminannya adalah penerimaan tepat satu kali: percobaan ulang yang cocok dalam tiga jam harus menghasilkan satu operasi yang diterima, meskipun Anda kehilangan responsnya.
Anda memilih kunci, maksimal 255 karakter, dan mempertahankannya di setiap percobaan ulang. Nilai stabil seperti welcome-user/usr_abc123 dapat mengidentifikasi satu operasi welcome-message setelah proses Anda dimulai ulang.
Header ini berlaku untuk permintaan yang mengubah data seperti POST, PATCH, dan DELETE. Permintaan tanpa kunci diproses tanpa deduplikasi ini. GET mengabaikan header ini karena membaca resource sudah aman untuk diulang.
Bird mengembalikan respons tersimpan untuk permintaan yang cocok dan sudah selesai, termasuk status dan body aslinya. Respons tersebut membawa Idempotency-Replay: true, sehingga Anda dapat mengidentifikasi penggunaan ulang itu di log Anda.
Panduan idempotensi mendokumentasikan default tiga jam untuk jendela respons selesai. Percobaan ulang setelah jendela itu berakhir dapat berjalan sebagai operasi baru. Jangan mengandalkan kunci itu secara permanen untuk mencegah pengiriman duplikat.
SDK Bird menghasilkan kunci untuk mutasi dan menggunakannya kembali di seluruh percobaan ulang internalnya. Bird CLI juga menghasilkan kunci untuk permintaan yang mengubah data jika tidak ada kunci. Tetapkan --idempotency-key secara eksplisit jika pemanggilan perintah terpisah harus berbagi operasi yang sama.
Untuk pengiriman SMTP, gunakan header pesan X-Bird-Idempotency-Key. Ini memungkinkan pengiriman ulang mengidentifikasi operasi yang sama.
Apa yang terjadi jika saya menggunakan kembali kunci secara salah?
Bird menolak penggunaan kunci yang bertentangan alih-alih mengembalikan respons untuk operasi yang berbeda.
| Situasi | Respons dan pemulihan |
|---|---|
| Kunci dan permintaan sama, respons disimpan | Respons tersimpan selama masa retensi, dengan Idempotency-Replay: true. |
| Kunci selesai digunakan ulang untuk permintaan berbeda | 409 dengan E01005, artinya penggunaan ulang kunci idempotensi. Perbaiki kunci sebelum mencoba ulang. |
| Permintaan lain dengan kunci itu masih berjalan | 409 dengan E01004, artinya permintaan sedang berlangsung. Tunggu sebentar dan coba lagi. |
| Kunci melebihi 255 karakter | 422 dengan E01001 pada endpoint yang mendeklarasikan header ini. Persingkat kunci. |
Perbandingan mencakup method, endpoint, parameter path, query string, dan body. Untuk JSON, mengubah spasi berarti mengubah identitas permintaan, jadi pertahankan body asli saat mencoba ulang.
Jika permintaan asli masih berjalan, tunggu sebelum mencoba ulang. Pertahankan kunci dan permintaan yang sama agar percobaan ulang mengidentifikasi operasi asli.
API tidak menyimpan respons 5xx sebagai respons selesai. Coba ulang timeout atau kesalahan server dengan backoff terbatas, kunci yang sama, dan permintaan yang identik dalam tiga jam. Jaminan penerimaan tepat satu kali juga mencakup respons yang hilang.
Penolakan 4xx dapat disimpan. Gunakan kunci baru untuk permintaan yang sudah diperbaiki: percobaan ulang tanpa perubahan akan memutar ulang penolakan yang tersimpan, dan input yang berubah akan berkonflik dengan kunci yang tersimpan itu.
Mengapa saya menerima webhook yang sama dua kali?
Bird dapat mencoba lagi pengiriman event yang sudah disimpan penerima Anda jika tidak menerima respons sukses.
Penerima dapat menyimpan event sesaat sebelum koneksinya terputus. Bird tidak melihat acknowledgment sukses dan mencoba ulang, meskipun penerima sudah memiliki event tersebut.
Setiap percobaan ulang mempertahankan header webhook-id yang sama, yang mengidentifikasi event. Pemutaran ulang pengiriman yang gagal juga mempertahankan identifier tersebut, sehingga keduanya dapat dikenali sebagai event yang sama.
Bagaimana cara membuat handler saya idempoten?
Simpan setiap webhook-id dengan constraint unik di database sebelum menjadwalkan pekerjaan event tersebut.
Memeriksa baris yang sudah ada sebelum menyisipkan menyisakan celah race condition: dua permintaan bersamaan bisa sama-sama tidak melihat baris. Biarkan database yang menolak identifier duplikat.
Simpan identifier dan job dalam transaksi yang sama. Ini mencegah identifier tercatat tanpa pekerjaan yang diantrekan.
- Verifikasi permintaan, lalu sisipkan identifier dan job-nya dalam transaksi yang sama.
- Kembalikan
2xxsetelah transaksi itu di-commit, agar Bird dapat berhenti mencoba ulang. - Proses job yang tersimpan di worker yang dapat mengulangi tindakannya sendiri dengan aman.
Untuk identifier duplikat yang sudah di-commit, kembalikan sukses tanpa membuat job lain. Untuk transaksi yang gagal, kembalikan error agar Bird mencoba ulang.
Jauhkan pekerjaan berat dari penerima karena menunggunya dapat menyebabkan permintaan timeout. Worker dapat mencoba lagi karena alasan yang tidak terkait pengiriman webhook, jadi melindungi penerima saja tidak cukup.
Event juga dapat tiba tidak berurutan. Bandingkan waktu event di timestamp sebelum menimpa state yang lebih baru. Percobaan ulang webhook gagal mencakup contoh biaya parsial.
Apa yang tidak boleh saya andalkan?
Jangan berasumsi bahwa deduplikasi permintaan membuat efek samping duplikat mustahil terjadi.
Untuk operasi tulis HTTP yang didukung, Bird mengaitkan kunci idempotensi dengan workspace atau organisasi permintaan tersebut. Operasi staf yang didukung menggunakan akun staf yang bertindak sebagai gantinya. Jika perlindungan tidak tersedia, Bird mengembalikan 503 E01033 IdempotencyUnavailable sebelum menjalankan percobaan tersebut. Hal ini tidak menentukan hasil percobaan sebelumnya. Jaminan penerimaan tepat satu kali mencakup percobaan ulang yang cocok dalam tiga jam. Periksa status pesan untuk memastikan pengiriman. Jika percobaan ulang sudah habis atau jendela waktunya berakhir, periksa hasil operasi asli sebelum mengirim lagi.
Demikian pula, webhook-id membedakan pengiriman berulang dari satu event. Event terpisah memiliki identifier terpisah. Aplikasi Anda tetap menentukan apakah event tersebut membenarkan pengulangan tindakan yang sama.
Idempotensi mendokumentasikan perilaku percobaan ulang API. Webhook membahas jaminan pengiriman terpisah yang ditangani penerima Anda.
Singkatnya
Percobaan ulang API dan percobaan ulang webhook memerlukan catatan yang berbeda.
Gunakan kembali Idempotency-Key untuk permintaan ke Bird. Penerima Anda menyimpan webhook-id untuk mengenali event yang sudah diterima.
Penolakan juga dapat disimpan.
Penolakan yang disimpan akan diputar ulang. Permintaan yang sudah diperbaiki memerlukan kunci baru karena inputnya berbeda.
Kunci yang sudah selesai tidak dapat mengidentifikasi permintaan yang berbeda.
Body atau endpoint JSON yang berubah dapat menghasilkan konflik 409. Perbaiki kuncinya, bukan mencoba ulang konflik tersebut tanpa perubahan.
Deduplikasi memiliki batasan.
Jaminan API mencakup penerimaan tepat satu kali untuk percobaan ulang yang cocok dalam tiga jam. Penerima webhook Anda memerlukan catatan event tahan lama miliknya sendiri.