Changelog webhook: breaking change yang tak diminta
5 menit baca
Changelog API REST ada karena pemanggil bisa memilih menolak response yang tidak dia mengerti, atau setidaknya mencatat error cukup keras hingga seseorang menyadarinya. Penerima webhook jarang melakukan salah satu dari itu. Dia menerima POST, membaca field yang diharapkan, dan jika sebuah field pindah, berubah tipe, atau hilang, endpoint itu diam-diam crash di dalam job latar belakang yang tidak diawasi siapa pun atau, lebih buruk, terus berjalan dengan nilai salah yang tidak pernah divalidasinya. Apa itu breaking change membahas definisi umum; payload webhook butuh jawabannya sendiri, karena mode kegagalannya berbeda dari endpoint yang sengaja dipanggil seseorang.
Mengapa perubahan payload webhook rusak berbeda dari perubahan response API?
Karena arah requestnya terbalik. Pemanggil REST memulai panggilan dan bisa menambahkan header versi, mencoba lagi saat 4xx, atau membaca pemberitahuan deprecation di response. Penerima webhook tidak memulai satu pun dari itu: server Anda yang memutuskan mengirim, memutuskan kapan, dan memutuskan bentuk apa yang akan dimiliki body itu. Satu-satunya pengungkit penerima adalah validasi yang ditulisnya saat integrasi dibangun, dan sebagian besar integrasi dibangun sekali, berfungsi, dan tidak pernah ditinjau ulang sampai rusak. Asimetri itulah seluruh alasan mengapa perubahan payload webhook layak mendapat lebih banyak kehati-hatian daripada perubahan yang sama pada body response yang secara aktif diminta pemanggil.
Apa yang sebenarnya dihitung sebagai breaking change dalam payload webhook?
| Perubahan | Breaking bagi kebanyakan penerima |
|---|---|
| Menambah field baru | Tidak, jika penerima mengabaikan field yang tidak dikenal (verifikasi asumsi ini, jangan anggap begitu saja) |
| Menghapus field | Ya, jika ada yang membacanya |
| Mengganti nama field | Ya, secara fungsional identik dengan menghapus yang lama |
| Mengubah tipe field (string ke object) | Ya, hampir selalu |
| Menyusun ulang field dalam body JSON | Tidak, untuk penerima mana pun yang mengurai berdasarkan key, yang seharusnya semua |
| Mengubah nama atau tipe event | Ya, jika penerima memfilter atau merutekan berdasarkan itu |
Baris “menambah field itu aman” adalah yang paling diandalkan tim dan yang paling layak diverifikasi, bukan diasumsikan. Parser JSON yang permisif mengabaikan field tidak dikenal secara default, tapi penerima yang deserialize ke skema ketat, beberapa bahasa bertipe melakukan ini tanpa konfigurasi tambahan, bisa menolak seluruh payload begitu field yang tak terduga muncul. Menambah field aman untuk webhook Anda hanya jika Anda tahu bagaimana penerima mengurai, bukan karena JSON sendiri permisif.
Bagaimana cara memberi versi pada payload webhook?
Mirip dengan response API, dengan satu perbedaan: penerima tidak pernah mengirim request, jadi
tidak bisa meminta versi, dan pengirimlah yang harus menyatakannya. Versi itu bisa ada di body atau
di header request pada pengiriman itu sendiri; pengiriman GitHub
membawa X-GitHub-Event dan X-GitHub-Hook-ID, dan
spesifikasi Standard Webhooks
menaruh metadatanya di header webhook-*. Field
versi dalam payload ("payload_version": 2) adalah opsi termurah dan berfungsi ketika penerima
bersedia bercabang berdasarkan itu. Tipe event bervers (invoice.updated menjadi
invoice.updated.v2 sebagai event terpisah yang diikuti sukarela oleh penerima) butuh lebih
banyak kerja untuk dibangun tapi berarti bentuk lama terus mengalir ke siapa pun yang tidak pernah
migrasi, yang lebih penting di sini daripada di endpoint REST karena Anda tidak bisa menelepon
setiap penerima untuk memintanya update. Pengaturan per langganan, dipilih saat pendaftaran
endpoint webhook, memajukan keputusan alih-alih bercabang di setiap pengiriman, dan merupakan
pilihan tepat saat Anda sudah punya catatan langganan untuk melampirkannya.
POST /endpoint-penerima
{
"event": "invoice.updated",
"payload_version": 2,
"data": { "invoice_id": "inv_123", "status": "paid" }
}
Bagaimana Anda bahkan tahu siapa yang mendengarkan?
Lebih buruk dari versi setara masalah ini dalam changelog API, karena webhook tidak punya log request masuk di sisi Anda yang menyebutkan pemanggil; Anda hanya punya log pengiriman keluar Anda sendiri, yang memberi tahu bahwa endpoint menerima 200, bukan apa yang dilakukannya dengan body itu. Lacak setidaknya dua hal: setiap endpoint terdaftar dengan pemiliknya, disiplin yang sama yang direkomendasikan changelog API internal untuk konsumen internal, dan tingkat kegagalan pengiriman per endpoint Anda setelah perubahan payload. Lonjakan response 4xx atau 5xx dari sebuah endpoint tepat setelah perubahan adalah hal terdekat dengan stack trace yang akan Anda dapatkan, dan sering kali itu satu-satunya sinyal bahwa penerima rusak, karena tim yang mengoperasikannya mungkin tidak menyadarinya selama berhari-hari.
Haruskah changelog webhook terpisah dari changelog API?
Bagian terpisah di halaman yang sama, bukan publikasi terpisah. Changelog API sudah menetapkan siapa yang membacanya dan bagaimana berlangganan; perubahan payload webhook termasuk dalam feed yang sama, dilabeli cukup jelas sehingga developer di sisi penerima yang memindai “apakah ini memengaruhi integrasi saya” bisa menyaringnya, karena konsumen webhook sering tidak punya alasan lain untuk memeriksa changelog API umum dan hanya akan menemukannya jika seseorang mengarahkannya langsung ke sana.
Seperti apa jendela deprecation yang wajar untuk payload webhook?
Lebih panjang dari deprecation REST yang setara, karena migrasi di sisi penerima biasanya berarti
tim kedua, yang mungkin tidak Anda hubungi langsung, harus menyadarinya, menjadwalkannya, dan
merilisnya tanpa urgensi sendiri. Satu bulan adalah batas bawah yang wajar untuk field yang
mungkin masih diurai penerima dengan library yang permisif; tiga bulan atau lebih lebih aman
untuk penghapusan field yang akan ditolak sepenuhnya oleh skema ketat. Kirim bentuk lama dan baru
bersamaan selama jendela ketika memungkinkan (field lama status dan penggantinya di versi 2
dalam payload yang sama), karena penerima yang membaca field lama terus berfungsi
tanpa menyentuh kodenya, dan yang sudah migrasi cukup mengabaikan field yang tidak dibutuhkannya
lagi.
FAQ
Apakah konsumen webhook perlu mengonfirmasi perubahan payload sebelum dirilis? Tidak ada mekanisme konfirmasi secara default, dan justru karena itu jendela deprecation lebih penting di sini daripada di API REST: tidak ada yang mengonfirmasi kesiapan, jadi jendelanya harus cukup panjang agar sebagian besar penerima migrasi dengan jadwal mereka sendiri sebelum bentuk lama menghilang.
Apakah pernah aman menambah field yang tidak dikenal tanpa pemberitahuan? Hanya setelah Anda memverifikasi, bukan mengasumsikan, bahwa penerima Anda mengurai secara permisif. Entri changelog murah dan menghilangkan tebak-tebakan; menambah field diam-diam dengan asumsi “parser JSON mengabaikan yang ekstra” merusak penerima mana pun dengan deserialisasi ketat.
Apa cara tercepat mendeteksi penerima webhook yang rusak setelah perubahan payload? Tingkat kegagalan pengiriman per endpoint, diamati dalam jam-jam segera setelah perubahan. Ini tidak akan memberi tahu apa yang rusak, hanya bahwa sesuatu rusak, tapi itu sinyal paling awal dan sering kali satu-satunya yang akan Anda dapatkan.
Apakah logika retry membantu penerima bertahan dari perubahan payload? Tidak. Retry mengirim ulang payload baru yang sama; ini tidak kembali ke bentuk yang bisa diurai penerima. Perubahan payload merusak penerima pada pengiriman pertama dan setiap retry berikutnya secara identik.
Klaim teknis dalam artikel ini belum ditinjau secara independen. Jika ada yang keliru, beri tahu kami dan kami akan memperbaikinya.