API değişiklikleri

Webhook changelog'ları: kimsenin istemediği breaking change

4 dk okuma

Bir REST API changelog’u var olur çünkü çağıran anlamadığı bir yanıtı reddedebilir, ya da en azından biri fark edecek kadar gürültülü bir hata loglayabilir. Bir webhook alıcısı bunların hiçbirini nadiren yapar. Bir POST alır, beklediği alanları okur, ve bir alan taşınmış, tipi değişmiş veya kaybolmuşsa, endpoint ya kimsenin izlemediği bir arka plan işinde sessizce çöker ya da, daha kötüsü, hiç doğrulamadığı yanlış bir değerle çalışmaya devam eder. Breaking change nedir genel tanımı ele alır; bir webhook payload’u kendi cevabına ihtiyaç duyar, çünkü başarısızlık modu birinin bilerek çağırdığı bir endpoint’ten farklıdır.

Bir webhook payload değişikliği bir API yanıt değişikliğinden neden farklı bozulur?

Çünkü isteğin yönü tersine dönmüştür. Bir REST çağıranı çağrıyı başlatır ve bir sürüm başlığı ekleyebilir, 4xx’te yeniden deneyebilir veya yanıtta bir kullanımdan kaldırma bildirimi okuyabilir. Bir webhook alıcısı bunların hiçbirini başlatmadı: sunucunuz göndermeye karar verdi, ne zaman göndereceğine karar verdi, ve gövdenin ne şekilde olacağına karar verdi. Alıcının tek kaldıracı entegrasyon kurulurken yazdığı doğrulamadır, ve çoğu entegrasyon bir kez kurulur, çalışır, ve bozulana kadar kimse tekrar bakmaz. Bu asimetri, bir webhook payload değişikliğinin bir çağıranın aktif olarak istediği bir yanıt gövdesindeki aynı değişiklikten daha fazla dikkat hak etmesinin bütün nedenidir.

Bir webhook payload’unda gerçekte breaking change sayılan nedir?

DeğişiklikÇoğu alıcı için breaking mi
Yeni bir alan eklemekHayır, eğer alıcılar bilinmeyen alanları görmezden geliyorsa (bu varsayımı doğrulayın, kabul etmeyin)
Bir alanı kaldırmakEvet, bir şey onu okuyorsa
Bir alanı yeniden adlandırmakEvet, eskisini kaldırmakla işlevsel olarak aynı
Bir alanın tipini değiştirmek (string’den objeye)Evet, neredeyse her zaman
JSON gövdesindeki alanları yeniden sıralamakHayır, anahtara göre parse eden herhangi bir alıcı için, ki hepsi böyle olmalı
Event adını veya tipini değiştirmekEvet, alıcılar buna göre filtreliyor veya yönlendiriyorsa

“Bir alan eklemek güvenlidir” satırı ekiplerin en çok dayandığı ve varsaymak yerine doğrulamaya en değer olanıdır. İzin verici bir JSON parser’ı varsayılan olarak bilinmeyen alanları görmezden gelir, ama katı bir şemaya deserialize eden bir alıcı, birkaç tipli dil bunu ek yapılandırma olmadan yapar, beklenmedik bir alan belirdiği anda tüm payload’u reddedebilir. Bir alan eklemek webhook’unuz için ancak alıcıların nasıl parse ettiğini bildiğinizde güvenlidir, JSON’un kendisi izin verici olduğu için değil.

Bir webhook payload’u nasıl versiyonlanır?

Bir API yanıtına çok benzer, bir farkla: alıcı hiçbir zaman istek göndermez, bu yüzden bir sürüm isteyemez, ve sürümü gönderen belirtmek zorundadır. Bu, gövdede veya teslimatın kendisindeki bir istek başlığında olabilir; GitHub’ın teslimatları X-GitHub-Event ve X-GitHub-Hook-ID taşır, ve Standard Webhooks spesifikasyonu meta verilerini webhook-* başlıklarına koyar. Payload’da bir sürüm alanı ("payload_version": 2) en ucuz seçenektir ve alıcılar buna göre dallanmaya istekliyse çalışır. Versiyonlu bir event tipi (invoice.updated, bir alıcının gönüllü olarak abone olduğu ayrı bir event olarak invoice.updated.v2 olur) kurması daha fazla iş gerektirir ama eski şeklin hiç migrate etmeyenlere akmaya devam etmesi anlamına gelir, ki bu bir REST endpoint’ine göre burada daha önemlidir çünkü her alıcıyı arayıp güncellemesini isteyemezsiniz. Webhook endpoint’i kaydedilirken seçilen abonelik başına bir ayar, kararı her teslimde dallanmak yerine önden alır, ve zaten bir abonelik kaydınız varsa ona bağlanacak doğru seçimdir.

POST /alici-endpoint
{
  "event": "invoice.updated",
  "payload_version": 2,
  "data": { "invoice_id": "inv_123", "status": "paid" }
}

Kimin dinlediğini bile nasıl bilirsiniz?

Bir API changelog’unda bu sorunun eşdeğerinden daha kötü, çünkü bir webhook’un sizin tarafınızda çağıranı adlandıran bir gelen istek günlüğü yoktur; sadece bir endpoint’in 200 aldığını söyleyen, gövdeyle ne yaptığını değil, kendi giden teslim günlüğünüz vardır. En azından iki şeyi takip edin: dahili API changelog’larının dahili tüketiciler için önerdiği aynı disiplinle, sahibi olan her kayıtlı endpoint, ve bir payload değişikliğinden sonra endpoint başına teslim başarısızlık oranınız. Bir değişiklikten hemen sonra bir endpoint’ten gelen 4xx veya 5xx yanıtlardaki bir sıçrama, alacağınız bir stack trace’e en yakın şeydir, ve genellikle bir alıcının bozulduğuna dair tek sinyaldir, çünkü onu işleten ekip bunu günlerce fark etmeyebilir.

Webhook changelog’u API changelog’undan ayrı olmalı mı?

Aynı sayfada ayrı bir bölüm, ayrı bir yayın değil. Bir API changelog’u zaten kimin okuduğunu ve nasıl abone olunduğunu belirler; bir webhook payload değişikliği aynı akışa aittir, alıcı tarafındaki bir geliştiricinin “bu benim entegrasyonumu etkiliyor mu” diye tarayarak filtreleyebileceği kadar açık etiketlenmiş, çünkü bir webhook tüketicisinin genel bir API changelog’unu kontrol etmek için genellikle başka bir nedeni yoktur ve onu ancak biri doğrudan oraya yönlendirirse bulur.

Bir webhook payload’u için makul bir kullanımdan kaldırma penceresi nasıl görünmeli?

Eşdeğer REST kullanımdan kaldırmasından daha uzun, çünkü alıcı tarafındaki migrasyon genellikle doğrudan bağlantınız olmayabilecek ikinci bir ekibin bunu fark etmesi, planlaması ve kendi aciliyeti olmadan yayınlaması anlamına gelir. Bir ay, alıcının muhtemelen hâlâ izin verici bir kütüphaneyle parse ettiği bir alan için makul bir alt sınırdır; katı bir şemanın tamamen reddedeceği bir alan kaldırma için üç ay veya daha fazlası daha güvenlidir. Mümkünse pencere boyunca eski ve yeni şekli birlikte gönderin (eski status alanı ve onun sürüm 2’deki karşılığı aynı payload’da), çünkü eski alanı okuyan bir alıcı kodunu değiştirmeden çalışmaya devam eder, ve zaten migrate etmiş biri artık ihtiyaç duymadığı alanı sadece görmezden gelir.

FAQ

Webhook tüketicileri yayınlanmadan önce bir payload değişikliğini onaylamak zorunda mı? Varsayılan olarak bir onay mekanizması yoktur, ve tam da bu yüzden kullanımdan kaldırma penceresi burada bir REST API’den daha önemlidir: kimse hazır olduğunu onaylamaz, bu yüzden pencere eski şekil kaybolmadan önce çoğu alıcının kendi zamanında migrate etmesine yetecek kadar uzun olmalı.

Bilinmeyen alanları uyarı olmadan eklemek hiç güvenli midir? Sadece alıcılarınızın izin verici parse ettiğini varsaymak yerine doğruladıktan sonra. Bir changelog kaydı az maliyetlidir ve tahmin unsurunu ortadan kaldırır; “JSON parser’ları extraları görmezden gelir” varsayımıyla sessizce alan eklemek katı deserialize eden herhangi bir alıcıyı bozar.

Bir payload değişikliğinden sonra bozuk bir webhook alıcısını tespit etmenin en hızlı yolu nedir? Değişiklikten hemen sonraki saatlerde izlenen, endpoint başına teslim başarısızlık oranı. Size ne bozulduğunu söylemez, sadece bir şeyin bozulduğunu, ama alacağınız en erken ve genellikle tek sinyaldir.

Yeniden deneme mantığı alıcıların bir payload değişikliğini atlatmasına yardımcı olur mu? Hayır. Bir yeniden deneme aynı yeni payload’u tekrar gönderir; alıcının parse edebileceği bir şekle dönmez. Bir payload değişikliği bir alıcıyı ilk teslimde ve sonraki her yeniden denemede aynı şekilde bozar.


Bu yazıdaki teknik iddialar bağımsız olarak kontrol edilmedi. Yanlış bir şey varsa bize söyle, düzeltelim.

changeloop'ta ilgili sayfalar: Geliştirici dokümantasyonu, Changelog araçları karşılaştırması

changeloop
Döngüyü kapatan bir changelog geliştiren ekip. Kullanıcıların bir şey ister, ekibin teslim eder, isteyen kişi haberdar olur.