हस्ताक्षर सत्यापन, इडेम्पोटेंसी कुंजियाँ, रिप्ले सुरक्षा, और ग्राहक-रिपोर्ट की गई त्रुटियों के लिए तेज़ डिबगिंग वर्कफ़्लो के साथ विश्वसनीय वेबहुक एकीकरण सीखें।
जब कोई कहता है “वेबहुक टूट रहे हैं,” तो वे आम तौर पर तीन में से एक बात मतलब रखते हैं: इवेंट्स कभी नहीं पहुँचे, इवेंट्स दो बार पहुँचे, या इवेंट्स किसी उलझन भरे क्रम में पहुँचे। उनके नज़रिये से सिस्टम ने कुछ “मिस” कर दिया। आपके नज़रिये से, प्रोवाइडर ने भेजा था, लेकिन आपका एंडपॉइंट स्वीकार नहीं किया, प्रोसेस नहीं हुआ, या आपने उसे उस तरह रिकॉर्ड नहीं किया जैसा आप उम्मीद करते थे।
वेबहुक पब्लिक इंटरनेट पर रहते हैं। रिक्वेस्ट्स में देरी होती है, रिट्राई होते हैं, और कभी-कभी आउट-ऑफ-आर्डर डिलीवरी होती है। ज़्यादातर प्रोवाइडर टाइमआउट्स या नॉन-2xx रेस्पॉन्स पर आक्रामक रूप से रिट्राई करते हैं। एक छोटा झटका (देर से चलने वाला डेटाबेस, डिप्लॉय, एक अल्पकालिक आउटेज) डुप्लिकेट्स और रेस कंडीशन्स में बदल सकता है।
खराब लॉग्स इसे यादृच्छिक महसूस कराते हैं। यदि आप साबित नहीं कर सकते कि कोई रिक्वेस्ट प्रामाणिक थी, तो आप उस पर सुरक्षित रूप से कार्रवाई नहीं कर सकते। यदि आप किसी ग्राहक की शिकायत को एक विशिष्ट डिलीवरी अटेम्प्ट से जोड़ नहीं सकते, तो आप अनुमान लगाने लगते हैं।
अधिकांश वास्तविक विफलताएँ कुछ ही बकेट्स में आती हैं:
व्यावहारिक लक्ष्य सरल है: असली इवेंट्स को एक बार स्वीकार करें, नकली रोकेँ, और ऐसा स्पष्ट ट्रेल छोड़ें ताकि आप ग्राहक रिपोर्ट को मिनटों में डिबग कर सकें।
वेबहुक सिर्फ एक HTTP रिक्वेस्ट है जिसे प्रोवाइडर आपके द्वारा एक्सपोज़ किए गए एंडपॉइंट पर भेजता है। आप इसे API कॉल की तरह पुल नहीं करते। भेजने वाला इसे तब पुश करता है जब कुछ होता है, और आपका काम इसे रिसीव करना, तेज़ी से प्रतिक्रिया देना और सुरक्षित रूप से प्रोसेस करना है।
एक सामान्य डिलीवरी में एक रिक्वेस्ट बॉडी (अक्सर JSON) और हेडर्स होते हैं जो आपको सत्यापित और ट्रैक करने में मदद करते हैं। कई प्रोवाइडर टाइमस्टैंप, इवेंट टाइप (जैसे invoice.paid) और एक यूनिक इवेंट ID भेजते हैं जिसे आप डुप्लीकेट डिटेक्ट करने के लिए स्टोर कर सकते हैं।
टीमों को चौंकाने वाली बात: डिलीवरी लगभग कभी “एक बार बिल्कुल” नहीं होती। ज़्यादातर प्रोवाइडर “at least once” के लक्ष्य पर होते हैं, जिसका मतलब है कि वही इवेंट कई बार आ सकता है, कभी-कभी मिनट या घंटे के अंतर पर।
रिट्राइज बोरिंग कारणों से होते हैं: आपका सर्वर धीमा है या टाइमआउट हो गया, आप 500 लौटाते हैं, उनका नेटवर्क आपका 200 नहीं देख पाया, या आपका एंडपॉइंट डिप्लॉय के दौरान या ट्रैफ़िक स्पाइक में अस्थायी रूप से उपलब्ध नहीं था।
एक टाइमआउट खासकर पेचीदा होता है। आपका सर्वर रिक्वेस्ट प्राप्त कर सकता है और प्रोसेस भी पूरा कर सकता है, लेकिन प्रतिक्रिया भेजने में देरी होने पर भेजने वाले को यह विफल दिखाई दे सकती है। प्रोवाइडर फिर रिट्राई करता है। सुरक्षा के बिना, आप वही इवेंट दो बार प्रोसेस कर सकते हैं।
एक अच्छा मानसिक मॉडल यह है कि HTTP रिक्वेस्ट को एक “डिलीवरी अटेम्प्ट” के रूप में ट्रीट करें, न कि “इवेंट” के रूप में। इवेंट उसकी ID से पहचाना जाता है। आपका प्रोसेसिंग उसी ID पर आधारित होना चाहिए, न कि इस पर कि प्रोवाइडर ने कितनी बार आपको कॉल किया।
वेबहुक सिग्निंग वह तरीका है जिससे भेजने वाला साबित करता है कि रिक्वेस्ट वास्तव में उसी ने भेजी और रास्ते में बदली नहीं गई। सिग्निंग के बिना, कोई भी जो आपके वेबहुक URL का अंदाज़ा लगा ले, फेक “payment succeeded” या “user upgraded” इवेंट पोस्ट कर सकता है। और भी बुरा, एक असली इवेंट ट्रांज़िट में बदल भी सकता है (राशि, ग्राहक ID, इवेंट टाइप) और तब भी आपकी ऐप को वैध दिखाई दे सकता है।
सबसे सामान्य पैटर्न HMAC के साथ एक साझा सीक्रेट है। दोनों पक्ष वही सीक्रेट जानते हैं। भेजने वाला सटीक वेबहुक पेलोड (अक्सर रॉ रिक्वेस्ट बॉडी) लेकर उस सीक्रेट से HMAC बनाता है और सिग्नेचर को पेलोड के साथ भेजता है। आपका काम वही HMAC वही बाइट्स पर दोबारा बनाना और सिग्नेचर्स मिलते हैं या नहीं चेक करना है।
सिग्नेचर डेटा आम तौर पर एक HTTP हेडर में होता है। कुछ प्रोवाइडर वहां टाइमस्टैंप भी डालते हैं ताकि आप रिप्ले सुरक्षा जोड़ सकें। कम आम यह है कि सिग्नेचर JSON बॉडी में एम्बेड किया जाता है, जो रिस्कियर है क्योंकि पार्सर्स या री-सीरियलाइज़ेशन फ़ॉर्मेटिंग बदल सकते हैं और सत्यापन तोड़ सकते हैं।
सिग्नेचर्स की तुलना करते समय सामान्य स्ट्रिंग तुलना का उपयोग न करें। बेसिक तुलना समय-आधारित भेद प्रकट कर सकती है जो एक अटैकर को सही सिग्नेचर अनुमान लगाने में मदद करती है। अपने भाषा या क्रिप्टो लाइब्रेरी का constant-time comparison फ़ंक्शन उपयोग करें, और किसी भी मिसमैच पर रिजेक्ट कर दें।
यदि ग्राहक रिपोर्ट करता है कि “आपका सिस्टम एक इवेंट स्वीकार कर गया जिसे हमने कभी नहीं भेजा,” तो सिग्नेचर चेक से शुरुआत करें। यदि सिग्नेचर सत्यापन विफल होता है, तो आम तौर पर आपके पास सीक्रेट मिसमैच है या आप गलत बाइट्स हैश कर रहे हैं (उदाहरण: पार्स्ड JSON बजाय रॉ बॉडी)। यदि पास हो जाता है, तो आप भेजने वाले की पहचान पर भरोसा कर सकते हैं और डेडूपिंग, ऑर्डरिंग और रिट्राइज पर आगे बढ़ सकते हैं।
विश्वसनीय वेबहुक हैंडलिंग एक नीरस नियम से शुरू होती है: जो आपने प्राप्त किया है वही सत्यापित करें, न कि जो आप देखना चाहते थे।
बिलकुल उसी रॉ रिक्वेस्ट बॉडी बाइट्स को कैप्चर करें जैसा वह आया। सत्यापन से पहले JSON पार्स और री-सीरियलाइज़ न करें। सूक्ष्म अंतर (व्हाइटस्पेस, की ऑर्डर, यूनिकोड) बाइट्स बदल देते हैं और वैध सिग्नेचर्स को अमान्य दिखा सकते हैं।
फिर वह सटीक पेलोड बनाएं जिसे आपका प्रोवाइडर साइन करने की अपेक्षा करता है। कई सिस्टम एक स्ट्रिंग साइन करते हैं जैसे timestamp + "." + raw_body। टाइमस्टैंप केवल सजावट नहीं है—यह इसलिए है ताकि आप पुराने रिक्वेस्ट्स को रिजेक्ट कर सकें।
सही हैश (अक्सर SHA-256) और साझा सीक्रेट का उपयोग करके HMAC कंप्यूट करें। सीक्रेट को एक सुरक्षित स्टोर में रखें और इसे पासवर्ड की तरह ट्रीट करें।
अंत में, अपने कंप्यूट किए गए मान की तुलना सिग्नेचर हेडर से constant-time कंपैरिजन से करें। यदि मेल नहीं खाता तो 4xx लौटाएँ और रोक दें। "वैसे भी स्वीकार करें" मत करें।
एक त्वरित इम्प्लीमेंटेशन चेकलिस्ट:
एक ग्राहक रिपोर्ट करता है “वेबहुक काम करना बंद कर दिए” जब आपने JSON पार्सिंग मिडलवेयर जोड़ दिया था। आप सिग्नेचर मिसमैच देखते हैं, खासकर बड़े पेलोड्स पर। फ़िक्स अक्सर यह होता है कि सत्यापन किसी भी पार्सिंग से पहले रॉ बॉडी का उपयोग करके किया जाए, और लॉग में यह दिखे कि कौन सा कदम फेल हुआ (उदाहरण: "signature header missing" बनाम "timestamp outside allowed window")। यह एक छोटा सा बदलाव अक्सर डिबगिंग का समय घंटों से मिनटों में बदल देता है।
प्रोवाइडर इसीलिए रिट्राई करते हैं क्योंकि डिलीवरी गारंटीड नहीं है। आपका सर्वर एक मिनट के लिए डाउन हो सकता है, कोई नेटवर्क हॉप रिक्वेस्ट ड्रॉप कर सकता है, या आपका हैंडलर टाइमआउट कर सकता है। प्रोवाइडर मानता है "शायद यह काम कर गया" और वही इवेंट फिर से भेज देता है।
एक इडेम्पोटेंसी की वह रसीद नंबर है जिसका आप उपयोग करते हैं यह पहचानने के लिए कि आपने पहले से ही एक इवेंट प्रोसेस किया है। यह सुरक्षा फीचर नहीं है, और यह सिग्नेचर सत्यापन का स्थान नहीं लेता। यह रेस कंडीशन्स नहीं ठीक करता जब तक आप इसे समवर्ती तरीके से सुरक्षित रूप से स्टोर और चेक न करें।
कुंजी चुनना इस पर निर्भर करता है जो प्रोवाइडर आपको देता है। उन मानों को प्राथमिकता दें जो रिट्राइज के दौरान स्थिर रहते हैं:
जब आप वेबहुक प्राप्त करते हैं, तो यूनिकनेस नियम के साथ पहले की को स्टोरेज में लिखें ताकि केवल एक रिक्वेस्ट “जीते।” फिर इवेंट को प्रोसेस करें। यदि आप वही की फिर से देखते हैं, तो सफलता लौटाएँ बिना काम दोहराए।
अपनी स्टोर की गई “रसीद” छोटी लेकिन उपयोगी रखें: की, प्रोसेसिंग स्टेटस (received/processed/failed), टाइमस्टैम्प्स (first seen/last seen), और एक न्यूनतम सारांश (इवेंट टाइप और संबंधित ऑब्जेक्ट ID)। कई टीमें 7 से 30 दिनों तक कीज़ रखती हैं ताकि लेट रिट्राइज और अधिकांश ग्राहक रिपोर्ट कवर हो सकें।
रिप्ले सुरक्षा एक सरल लेकिन खतरनाक समस्या रोकती है: कोई असली वेबहुक रिक्वेस्ट (एक वैध सिग्नेचर के साथ) कैप्चर कर ले और उसे बाद में फिर से भेज दे। अगर आपका हैंडलर हर डिलीवरी को नया मानता है, तो वह रिप्ले डुप्लिकेट रिफंड, डुप्लिकेट यूज़र इनवाइट्स, या बार-बार स्टेट चेंज कर सकता है।
एक सामान्य तरीका है कि न सिर्फ पेलोड साइन किया जाए बल्कि टाइमस्टैंप भी साइन किया जाए। आपका वेबहुक हेडर्स जैसे X-Signature और X-Timestamp शामिल कर सकता है। रिसीव पर, सिग्नेचर वेरिफाई करें और यह भी चेक करें कि टाइमस्टैंप एक छोटे विंडो के अंदर ताज़ा है।
क्लॉक ड्रिफ्ट आम तौर पर गलत रिजेक्शन का कारण बनता है। आपके सर्वर और भेजने वाले के सर्वर मिनटों तक असहमति कर सकते हैं, और नेटवर्क डिलीवरी में देरी कर सकता है। थोड़ा ग्रेस रखें और रिजेक्शन का कारण लॉग करें।
प्रायोगिक नियम जो अच्छा काम करते हैं:
abs(now - timestamp) <= window (उदाहरण के लिए 5 मिनट प्लस छोटा ग्रेस)यदि टाइमस्टैंप गायब हैं, तो आप केवल समय के आधार पर सच्ची रिप्ले सुरक्षा नहीं कर सकते। उस स्थिति में, इडेम्पोटेंसी पर और ज़ोर दें (डुप्लीकेट इवेंट IDs स्टोर और रिजेक्ट करें) और अगली वेबहुक वर्जन में टाइमस्टैंप की आवश्यकता consider करें।
सीक्रेट रोटेशन भी मायने रखता है। यदि आप साइनिंग सीक्रेट्स रोटेट करते हैं, तो एक छोटा overlap पीरियड के लिए कई एक्टिव सीक्रेट रखें। पहले नए सीक्रेट से वेरिफाई करें, फिर पुराने पर fallback रखें। इससे रॉलआउट के दौरान ग्राहक ब्रेकेज़ नहीं होंगे। यदि आपकी टीम तेज़ी से एंडपॉइंट्स शिप करती है (उदाहरण के लिए, Koder.ai से कोड जेनरेट करना और स्नैपशॉट्स तथा रोलबैक का उपयोग करते हुए), तो वह overlap विंडो मददगार रहती है क्योंकि पुराने वर्ज़न थोड़ी देर के लिए लाइव रह सकते हैं।
रिट्राइज सामान्य हैं। मान लें कि हर डिलीवरी डुप्लीकेट, देरी या गलत क्रम वाली हो सकती है। आपका हैंडलर उसी तरह व्यवहार करे चाहे वह इवेंट एक बार देखें या पाँच बार।
रिक्वेस्ट पाथ को छोटा रखें। स्वीकार करने के लिए ज़रूरी काम ही करें, फिर भारी काम को बैकग्राउंड जॉब में भेज दें।
एक सरल पैटर्न जो प्रोडक्शन में टिकता है:
2xx तभी लौटाएँ जब आप सिग्नेचर को वेरिफाई कर चुके हों और इवेंट रिकॉर्ड (या क्यू) कर चुका हों। यदि आप 200 पहले लौटाते हैं और कुछ भी सेव नहीं करते, तो क्रैश के दौरान इवेंट्स खो सकते हैं। यदि आप भारी काम करने से पहले रिप्लाइ कर देते हैं, तो टाइमआउट्स रिट्राइज ट्रिगर करते हैं और आप साइड-इफेक्ट्स को दोहराएंगे।
धीमे डाउनस्ट्रीम सिस्टम रिट्राइज को कष्टप्रद बनाते हैं। यदि आपका ईमेल प्रोवाइडर, CRM, या डेटाबेस धीमा है, तो एक क्यू को देरी सोखने दें। वर्कर बैकऑफ के साथ रिट्राइ कर सकता है, और आप अटके हुए जॉब्स पर अलर्ट कर सकते हैं बिना भेजने वाले को ब्लॉक किए।
आउट-ऑफ-ऑर्डर इवेंट्स भी होते हैं। उदाहरण के लिए, एक subscription.updated पहले आ सकता है और subscription.created बाद में। सहनशीलता बनाने के लिए वर्तमान स्थिति चेक करें, अपसर्ट्स की अनुमति दें, और “नॉट फाउंड” को स्थायी फ़ेल की बजाय बाद में retry होने वाली स्थिति समझें (जहाँ अर्थपूर्ण हो)।
कई “यादृच्छिक” वेबहुक इश्यू स्वयं-निर्मित होते हैं। वे flaky नेटवर्क की तरह दिखते हैं, लेकिन पैटर्न में दोहराते हैं, अक्सर डिप्लॉय के बाद, सीक्रेट रोटेशन के बाद, या पार्सिंग में छोटे बदलाव के बाद।
सबसे आम सिग्नेचर बग गलत बाइट्स हैश करना है। यदि आप पहले JSON पार्स करते हैं, तो आपका सर्वर इसे री-फॉर्मेट कर सकता है (व्हाइटस्पेस, की आर्डर, नंबर फॉर्मैटिंग)। फिर आप उस बॉडी के खिलाफ सिग्नेचर वेरिफाई करते हैं जो भेजने वाले ने साइन नहीं किया, और सत्यापन विफल हो जाता है भले ही पेलोड असली हो। हमेशा रॉ रिक्वेस्ट बॉडी बाइट्स के खिलाफ सत्यापित करें जैसा वह प्राप्त हुआ।
अगला बड़ा भ्रम सीक्रेट्स हैं। टीमें स्टेजिंग में टेस्ट करती हैं लेकिन गलती से प्रोडक्शन सीक्रेट से वेरिफाई कर देती हैं, या रोटेशन के बाद पुराना सीक्रेट रखते हैं। जब कोई ग्राहक रिपोर्ट बताता है कि "केवल एक वातावरण में विफलता" हो रही है, तो पहले गलत सीक्रेट या गलत कॉन्फ़िग मान लें।
कुछ गलतियाँ जो लंबी जांचों में बदल जाती हैं:
उदाहरण: एक ग्राहक कहता है "order.paid कभी नहीं पहुँचा।" आप सिग्नेचर फेल्यर्स देखते हैं जो एक रिफैक्टर के बाद शुरू हुए जो रिक्वेस्ट पार्सिंग मिडलवेयर बदल गया। मिडलवेयर JSON पढ़ता और दोबारा एन्कोड करता है, इसलिए आपका सिग्नेचर चेक अब संशोधित बॉडी उपयोग कर रहा था। फिक्स सरल है, लेकिन तब ही जब आप सही जगह देखें।
जब कोई ग्राहक कहता है "आपका वेबहुक नहीं चला," इसे अनुमान नहीं बल्कि ट्रेस की समस्या की तरह ट्रीट करें। प्रोवाइडर के एक सटीक डिलीवरी अटेम्प्ट पर एंकर करें और उसे अपने सिस्टम में फॉलो करें।
शुरू करें प्रोवाइडर के डिलीवरी आइडेंटिफ़ायर, रिक्वेस्ट ID, या इवेंट ID से। उस एक वैल्यू के साथ आप मिलान लॉग एंट्री जल्दी खोज सकें।
उसके बाद तीन चीजें क्रम से चेक करें:
फिर पुष्टि करें कि आपने प्रोवाइडर को क्या लौटाया। एक धीमा 200 उतना ही खराब हो सकता है जितना 500 यदि प्रोवाइडर टाइमआउट कर देता है और रिट्राई करता है। स्थिति कोड, प्रतिक्रिया समय, और क्या आपका हैंडलर भारी काम करने से पहले स्वीकार कर चुका था देखें।
यदि आप पुन:उत्पादन करना चाहते हैं, तो सुरक्षित तरीके से करें: एक रेडैक्टेड रॉ रिक्वेस्ट सैंपल (प्रमुख हेडर्स और रॉ बॉडी) स्टोर करें और उसी सीक्रेट और सत्यापन कोड के साथ परीक्षण वातावरण में रीप्ले करें।
जब वेबहुक इंटीग्रेशन "यादृच्छिक रूप से" फेल होना शुरू करे, तो स्पीड पर फोकस करें न कि परफेक्शन पर। यह रनबुक सामान्य कारणों को पकड़ लेता है।
पहले एक ठोस उदाहरण लें: प्रोवाइडर नाम, इवेंट टाइप, लगभग टाइमस्टैंप (टाइमज़ोन के साथ), और कोई भी इवेंट ID जो ग्राहक देख पा रहा है।
फिर वेरिफाई करें:
यदि प्रोवाइडर कहता है "हमने 20 बार रिट्राई किया," तो पहले सामान्य पैटर्न चेक करें: गलत सीक्रेट (सिग्नेचर फेल), क्लॉक ड्रिफ्ट (रिप्ले विंडो), पेलोड साइज़ लिमिट्स (413), टाइमआउट्स (कोई रिस्पॉन्स), और डाउनस्ट्रीम से 5xx बर्स्ट।
एक ग्राहक ईमेल करता है: "हमें कल एक invoice.paid इवेंट मिस हुआ। हमारी सिस्टम ने कभी अपडेट नहीं किया।" यहाँ इसे ट्रेस करने का तेज़ तरीका है।
सबसे पहले पुष्टि करें कि प्रोवाइडर ने डिलीवरी की कोशिश की या नहीं। इवेंट ID, टाइमस्टैंप, डेस्टिनेशन URL, और आपका एंडपॉइंट जो सटीक रेस्पॉन्स कोड लौटा उसे निकालें। यदि रिट्राइज हुईं, तो पहले फेल होने का कारण और क्या किसी बाद के रिट्राई ने सफलता पाई यह नोट करें।
अगला, एज पर आपके कोड ने क्या देखा यह वेरिफाई करें: उस एंडपॉइंट के लिए कॉन्फ़िगर किया गया साइनिंग सीक्रेट क्या था, रॉ रिक्वेस्ट बॉडी का उपयोग करके सिग्नेचर वेरिफाई दोबारा करें, और प्राप्त रिक्वेस्ट टाइमस्टैंप को आपकी अलाउड विंडो के खिलाफ चेक करें।
रिट्राइज के दौरान रिप्ले विंडो से सावधान रहें। यदि आपकी विंडो 5 मिनट है और प्रोवाइडर 30 मिनट बाद रिट्राई करता है, तो आप वैध रिट्राई को रिजेक्ट कर सकते हैं। यदि यह आपकी नीति है, तो इसे इरादतन और डॉ큐मेंटेड रखें। यदि नहीं, तो विंडो चौड़ी करें या लॉजिक बदलें ताकि इडेम्पोटेंसी प्राथमिक रक्षा बनी रहे।
अगर सिग्नेचर और टाइमस्टैंप सही लगते हैं, तो इवेंट ID को अपने सिस्टम में फॉलो करें और जवाब दें: क्या आपने इसे प्रोसेस किया, डेड्यूप किया, या ड्रोप कर दिया?
आम परिणाम:
जब आप ग्राहक को जवाब दें, तो इसे संक्षिप्त और विशिष्ट रखें: “हमने 10:03 और 10:33 UTC पर डिलीवरी अटेम्प्ट्स प्राप्त किए। पहला 10s के बाद टाइमआउट हुआ; रिट्राई रिजेक्ट हुआ क्योंकि टाइमस्टैंप हमारे 5-मिनट विंडो के बाहर था। हमने विंडो बढ़ा दी और तेज़ स्वीकृति जोड़ी। यदि आवश्यक हो तो कृपया इवेंट ID X फिर से भेजें।”
वेबहुक आग रोकने का सबसे तेज़ तरीका यह है कि हर इंटीग्रेशन वही प्लेबुक फॉलो करे। उस कॉन्ट्रैक्ट को लिखें जिसे आप और भेजने वाला सहमत हैं: आवश्यक हेडर्स, सटीक साइनिंग मेथड, कौन सा टाइमस्टैंप उपयोग होगा, और किन IDs को आप यूनिक मानते हैं।
फिर हर डिलीवरी अटेम्प्ट के लिए आप जो रिकॉर्ड करते हैं उसे स्टैन्डर्डाइज़ करें। एक छोटा रसीद लॉग आम तौर पर काफी होता है: received_at, event_id, delivery_id, signature_valid, idempotency_result (new/duplicate), handler_version, और response status।
एक वर्कफ़्लो जो बढ़ते हुए भी उपयोगी रहता है:
यदि आप Koder.ai पर ऐप बनाते हैं (koder.ai), तो Planning Mode हेडर्स, सिग्निंग, IDs, और retry बिहेवियर पहले परिभाषित करने का अच्छा तरीका है और फिर विभिन्न प्रोजेक्ट्स में एक सुसंगत एंडपॉइंट और रसीद रिकॉर्ड जेनरेट करने में मदद करता है। वही कंसिस्टेंसी है जो डिबगिंग को तेज़ बनाती है बजाय हीरोइक प्रयास के।
क्योंकि वेबहुक डिलीवरी आम तौर पर at-least-once होती है, न कि exactly-once। प्रोवाइडर टाइमआउट्स, 5xx प्रतिक्रियाओं, या जब उन्हें आपका 2xx दिखाई नहीं देता तो रिट्राई करते हैं, इसलिए डुप्लिकेट्स, देरी और आउट-ऑफ-ऑर्डर डिलीवरी हो सकती है भले ही सब कुछ “सही” चल रहा हो।
डिफॉल्ट रूप से यह नियम अपनाएं: पहले सिग्नेचर सत्यापित करें, फिर इवेंट स्टोर/डेडूप करें, उसके बाद 2xx भेजें, और भारी काम असिंक्रोनस रूप से करें।
यदि आप भारी काम रिप्लाइ से पहले करते हैं तो टाइमआउट्स मिलेंगे और रिट्राइज ट्रिगर होंगे; अगर आप रिकॉर्ड किए बिना रिप्लाइ कर देते हैं तो क्रैश पर इवेंट्स खो सकते हैं।
सटीकता के लिए रॉ रिक्वेस्ट बॉडी बाइट्स का उपयोग करें जैसे वह आया था। सत्यापन से पहले JSON पार्स न करें और फिर दोबारा सीरियलाइज़ न करें—व्हाइटस्पेस, की आर्डर और नंबर फॉर्मैटिंग बदलने से सिग्नेचर टूट सकता है।
साथ ही सुनिश्चित करें कि आप प्रदाता द्वारा साइन किए गए पे-लोड को ठीक उसी तरह दोबारा बना रहे हैं (अकसर timestamp + "." + raw_body)।
एक 4xx (आम तौर पर 400 या 401) लौटाएँ और पेलोड प्रोसेस न करें।
एक छोटा कारण लॉग करें (जैसे missing signature header, mismatch, bad timestamp window), लेकिन सीक्रेट या पूरा संवेदनशील पेलोड लॉग न करें।
एक इडेम्पोटेंसी की एक स्थिर यूनिक पहचान है जिसे आप स्टोर करते हैं ताकि रिट्राइज साइड-इफेक्ट्स को दोबारा लागू न करें।
बेस्ट विकल्प:
कानूनी तौर पर इसे एक यूनिक कंस्ट्रेंट के साथ लागू करें ताकि concurrency में सिर्फ एक रिक्वेस्ट “जीते।”
पहले साइड-इफेक्ट्स करने के बजाय इडेम्पोटेंसी की को स्टोर करें, यूनिकनेस नियम के साथ। फिर:
यदि insert इसलिए फेल हो क्योंकि की पहले से मौजूद है, तो 2xx लौटाएँ और बिजनेस एक्शन स्किप करें।
साइन्ड डेटा में एक टाइमस्टैंप जोड़ें और एक छोटा विंडो लागू करें (उदाहरण: कुछ मिनट)।
कठोर नियम:
डिलीवरी ऑर्डर को इवेंट ऑर्डर न मानें। हैंडलर्स को सहनशील बनाएं:
इवेंट ID और टाइप स्टोर करें ताकि आप अजीब ऑर्डर में भी क्या हुआ समझ सकें।
हर डिलीवरी अटेम्प्ट पर एक छोटा “रसीद” लॉग करें ताकि आप एक इवेंट को एंड-टू-एंड ट्रेस कर सकें:
लॉग्स को event ID से सर्चेबल रखें ताकि सपोर्ट जल्दी ग्राहक रिपोर्ट्स का जवाब दे सके।
एक ठोस पहचान मांगें: event ID या delivery ID और लगभग समय।
फिर इस क्रम में चेक करें:
यदि आप Koder.ai पर एंडपॉइंट बनाते हैं, तो handler पैटर्न को हर प्रोजेक्ट में कंसिस्टेंट रखें (verify → record/dedupe → queue → respond)। कंसिस्टेंसी इन चेक्स को तेज़ बनाती है।