{"id":6,"date":"2025-07-24T10:00:00","date_gmt":"2025-07-24T07:00:00","guid":{"rendered":"https:\/\/www.hasangultekin.com\/2025\/07\/24\/webhooks-duplicates-and-delayed-events\/"},"modified":"2025-07-24T10:00:00","modified_gmt":"2025-07-24T07:00:00","slug":"webhooks-duplicates-and-delayed-events","status":"publish","type":"post","link":"https:\/\/www.hasangultekin.com\/tr\/2025\/07\/24\/webhooks-duplicates-and-delayed-events\/","title":{"rendered":"Yinelenen ve Gecikmeli Olaylar \u0130\u00e7in Webhook Tasar\u0131m\u0131"},"content":{"rendered":"<p>Webhook, ba\u015fka bir sistemden gelen bir bildirimdir. Bu bildirimi, \u201cbildirimi al, kayd\u0131 g\u00fcncelle ve ba\u015far\u0131 mesaj\u0131 g\u00f6nder\u201d \u015feklinde kusursuz bir talimat olarak ele almak cazip gelebilir. Ancak ger\u00e7ek entegrasyonlar, daha \u00f6zenli bir anla\u015fma gerektirir.<\/p>\n<p>Ayn\u0131 olay birden fazla kez gelebilir. Daha ge\u00e7 ger\u00e7ekle\u015fen bir olay \u00f6nce gelebilir. Al\u0131c\u0131 i\u015fini tamamlam\u0131\u015f olsa bile, g\u00f6nderen yan\u0131t\u0131 hi\u00e7 almad\u0131\u011f\u0131 i\u00e7in yeniden deneme yapabilir. Ben bu ko\u015fullar\u0131 g\u00f6z \u00f6n\u00fcnde bulundurarak en ba\u015f\u0131ndan itibaren tasar\u0131m\u0131m\u0131 yap\u0131yorum.<\/p>\n<h2>Al\u0131c\u0131 s\u0131n\u0131r\u0131n\u0131 k\u00fc\u00e7\u00fck tutun<\/h2>\n<p>Al\u0131c\u0131, teslimat\u0131 do\u011frulamal\u0131, temel yap\u0131s\u0131n\u0131 kontrol etmeli, kal\u0131c\u0131 olarak kaydetmeli ve sa\u011flay\u0131c\u0131n\u0131n protokol\u00fcne uygun olarak teslimat\u0131 teyit etmelidir. Daha sonra maliyetli i\u015f s\u00fcre\u00e7leri devreye girebilir.<\/p>\n<p>\u0130mza do\u011frulamas\u0131nda, sa\u011flay\u0131c\u0131 taraf\u0131ndan istenen temsil bi\u00e7imi kullan\u0131lmal\u0131d\u0131r. \u0130mza, orijinal istek baytlar\u0131n\u0131 kaps\u0131yorsa, JSON\u2019un \u00f6nce ayr\u0131\u015ft\u0131r\u0131lmas\u0131 ve yeniden serile\u015ftirilmesi, do\u011frulanacak i\u00e7eri\u011fi de\u011fi\u015ftirebilir. Do\u011frulama hatalar\u0131 hi\u00e7bir \u015fekilde normal i\u015fleme s\u00fcrecine aktar\u0131lmamal\u0131d\u0131r.<\/p>\n<p>Dayan\u0131kl\u0131l\u0131k da ayn\u0131 derecede \u00f6nemlidir. Olay\u0131n kaydedilmesinden \u00f6nce ba\u015far\u0131 bildirimi g\u00f6nderilmesi, i\u015flemin \u00e7\u00f6kebilece\u011fi ve g\u00f6nderenin kabul edildi\u011fini sand\u0131\u011f\u0131 verilerin kaybolabilece\u011fi bir zaman aral\u0131\u011f\u0131 yarat\u0131r. Bellek i\u00e7i kuyruk bu zaman aral\u0131\u011f\u0131n\u0131 ortadan kald\u0131rmaz.<\/p>\n<h2>Makbuzlar\u0131 ve i\u015f i\u015flemlerini tekille\u015ftirin<\/h2>\n<p>Sa\u011flay\u0131c\u0131y\u0131, ba\u011fl\u0131 hesab\u0131 ve olay tan\u0131mlay\u0131c\u0131s\u0131n\u0131 bir veritaban\u0131 benzersizlik k\u0131s\u0131tlamas\u0131 alt\u0131nda kaydediyorum. Bu sayede, e\u015fzamanl\u0131 olarak ger\u00e7ekle\u015fen m\u00fckerrer teslimatlar tek bir saklanan makbuzda birle\u015ftirilebiliyor.<\/p>\n<p>Ancak, bir olay kimli\u011fi her zaman bir i\u015f i\u015flemi kimli\u011fiyle ayn\u0131 de\u011fildir. \u0130ki farkl\u0131 olay, ayn\u0131 kayna\u011f\u0131 me\u015fru bir \u015fekilde tan\u0131mlayabilir veya ayn\u0131 sonraki eylemi tetikleyebilir. \u0130\u015f eyleminin kendine \u00f6zg\u00fc bir kimli\u011fi ve ge\u00e7i\u015f kurallar\u0131 olmas\u0131 gerekir.<\/p>\n<p><a href=\"https:\/\/docs.stripe.com\/webhooks\" target=\"_blank\" rel=\"noopener\">Stripe\u2019\u0131n webhook belgeleri<\/a> Yinelenen teslimatlar\u0131 a\u00e7\u0131k\u00e7a tan\u0131mlar ve teslimat s\u0131ras\u0131n\u0131 garanti etmez. Geli\u015ftirme oturumunda g\u00f6zlemlenen zamanlaman\u0131n bir s\u00f6zle\u015fme oldu\u011funu varsaymak yerine, al\u0131c\u0131 tasar\u0131m\u0131nda bu belgelenmi\u015f davran\u0131\u015flar\u0131 temel al\u0131yorum.<\/p>\n<h2>Geli\u015f s\u0131ras\u0131 yerine durum ge\u00e7i\u015flerini modelleyin<\/h2>\n<p>Bir abonelik entegrasyonunu g\u00f6z \u00f6n\u00fcnde bulundurun. Gecikmeli bir bildirim, daha g\u00fcncel bir durumu k\u00f6r\u00fc k\u00f6r\u00fcne \u00fczerine yazmamal\u0131d\u0131r. Bazen do\u011fru \u00e7\u00f6z\u00fcm, ge\u00e7erli ve g\u00fcncel kayna\u011f\u0131 almak ve yerel g\u00f6r\u00fcn\u00fcm\u00fc bununla uyumlu hale getirmektir.<\/p>\n<p>Ge\u00e7mi\u015fteki ge\u00e7i\u015fleri gerektiren i\u015flemlerde, olay\u0131 korur ve alana \u00f6zg\u00fc kurallar\u0131 uygular\u0131m. \u00d6zellikle birka\u00e7 de\u011fi\u015fiklik ayn\u0131 zaman damgas\u0131na sahip oldu\u011funda veya farkl\u0131 sistemler farkl\u0131 saatler kulland\u0131\u011f\u0131nda, s\u0131ralamay\u0131 belirlemek i\u00e7in sadece bir zaman damgas\u0131 yeterli olmayabilir.<\/p>\n<p>Karar, verilerin kullan\u0131m amac\u0131na ba\u011fl\u0131d\u0131r. Yerel bir durum rozeti i\u00e7in yaln\u0131zca g\u00fcncel durum yeterli olabilir. Bir defter veya denetim ge\u00e7mi\u015fi ise de\u011fi\u015fikliklerin ger\u00e7ek s\u0131ras\u0131n\u0131 ve anlam\u0131n\u0131 gerektirir. Tek bir genel \u201cson yazma ge\u00e7erli\u201d i\u015fleyicisi, her iki amac\u0131 da g\u00fcvenli bir \u015fekilde kar\u015f\u0131layamaz.<\/p>\n<h2>\u0130\u015fleme hatalar\u0131n\u0131 g\u00f6r\u00fcn\u00fcr hale getirin<\/h2>\n<p>Al\u0131m durumunu i\u015fleme durumundan ayr\u0131 tutuyorum. Kabul edilmi\u015f bir olay yine de beklemede, yeniden deneme a\u015famas\u0131nda, tamamlanm\u0131\u015f veya inceleme bekliyor durumda olabilir. Bu ayr\u0131m, sa\u011fl\u0131kl\u0131 bir HTTP yan\u0131t oran\u0131n\u0131n bozuk bir entegrasyonu gizlemesini \u00f6nler.<\/p>\n<p>Her i\u015fleme denemesi, s\u0131n\u0131rl\u0131 bir yeniden deneme politikas\u0131na sahip olmal\u0131d\u0131r. \u0130\u015flem ilerleyemedi\u011finde, bir inceleme kuyru\u011fu veya \u00f6l\u00fc mesaj kuyru\u011fu, olay referans\u0131n\u0131 ve hata nedenini saklamal\u0131d\u0131r. Olay\u0131n yeniden oynat\u0131lmas\u0131 s\u0131ras\u0131nda, orijinal denemede kullan\u0131lan tekille\u015ftirme ve yetkilendirme kurallar\u0131 uygulanmal\u0131d\u0131r.<\/p>\n<p>Yararl\u0131 \u00f6l\u00e7\u00fcmler aras\u0131nda, i\u015flenmemi\u015f en eski olay\u0131n ya\u015f\u0131, i\u015fleme gecikmesi, tekrarlanan hatalar ve mutabakat uyu\u015fmazl\u0131klar\u0131 say\u0131labilir. Bu \u00f6l\u00e7\u00fcmler, toplam webhook iste\u011fi say\u0131s\u0131ndan daha net bir \u015fekilde m\u00fc\u015fterinin ger\u00e7ek gecikmesini ortaya koyar.<\/p>\n<h2>A\u011f\u0131n neler yapabilece\u011fini test edin<\/h2>\n<p>Test dizilim, yinelenen teslimat, tersine \u00e7evrilmi\u015f var\u0131\u015f s\u0131ras\u0131, kal\u0131c\u0131 al\u0131m i\u015fleminden sonra meydana gelen bir \u00e7\u00f6kme ve harici bir yan etkiden sonra zaman a\u015f\u0131m\u0131 durumlar\u0131n\u0131 i\u00e7ermektedir. Ayr\u0131ca, ge\u00e7ersiz bir imzan\u0131n bekleyen bir i\u015f i\u015flemi bile olu\u015fturamayaca\u011f\u0131n\u0131 da kontrol ediyorum.<\/p>\n<p>\u0130yi tasarlanm\u0131\u015f bir webhook al\u0131c\u0131s\u0131, ekibe iki yararl\u0131 bilgi sa\u011flar: bildirimin g\u00fcvenli bir \u015fekilde kabul edilip edilmedi\u011fi ve hedeflenen i\u015f etkisinin ger\u00e7ekle\u015ftirilip ger\u00e7ekle\u015ftirilmedi\u011fi. Bu iki bilgiyi birbirinden ayr\u0131 tutmak, entegrasyonun i\u015fleyi\u015fini \u00e7ok daha kolayla\u015ft\u0131r\u0131r.<\/p>\n<p class=\"hg-editorial-note\"><small>25 Eyl\u00fcl 2026 tarihinde g\u00fcncellenmi\u015ftir.<\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>Giri\u015f verilerini do\u011frulayan, i\u015fleri kal\u0131c\u0131 olarak kabul eden, yinelenen teslimatlar\u0131 i\u015fleyen ve olaylar\u0131n ge\u00e7 geldi\u011fi durumlarda durumu senkronize eden webhook al\u0131c\u0131lar\u0131 olu\u015fturun.<\/p>","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"footnotes":""},"categories":[149],"tags":[169,170,195],"class_list":["post-6","post","type-post","status-publish","format-standard","hentry","category-backend-architecture","tag-idempotency","tag-integrations","tag-webhooks"],"_links":{"self":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts\/6","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/comments?post=6"}],"version-history":[{"count":0,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/posts\/6\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/media?parent=6"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/categories?post=6"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.hasangultekin.com\/tr\/wp-json\/wp\/v2\/tags?post=6"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}