ബാക്കെൻഡ് ട്യൂട്ടോറിയലുകളിലെ കെണി

ട്യൂട്ടോറിയലുകൾ നിങ്ങൾക്ക് ഒരു ലളിതമായ പ്രക്രിയയാണ് കാണിച്ചുതരുന്നത്. ഒരു വെബ്ഹുക്ക് (webhook) സ്വീകരിക്കുക. ഡാറ്റാബേസ് അപ്‌ഡേറ്റ് ചെയ്യുക. ഒരു 200 OK മറുപടി നൽകുക.

ടെസ്റ്റിംഗിൽ നിങ്ങളുടെ കോഡ് കൃത്യമായി പ്രവർത്തിക്കുന്നു. നിങ്ങൾ അത് പ്രൊഡക്ഷനിലേക്ക് മാറ്റുന്നു. എന്നാൽ പിന്നീട് നിങ്ങളുടെ ഡാറ്റാബേസിൽ ഡ്യൂപ്ലിക്കേറ്റ് റെക്കോർഡുകൾ കാണുന്നു. ഉപയോക്താക്കൾക്ക് രണ്ടുതവണ ക്രെഡിറ്റ് ലഭിക്കുന്നു. ഡാറ്റാ എൻട്രികൾ കുമിഞ്ഞുകൂടുന്നു.

നെറ്റ്‌വർക്ക് പരാജയങ്ങൾ (network failure) എന്ന യാഥാർത്ഥ്യത്തെ ട്യൂട്ടോറിയലുകൾ അവഗണിക്കുന്നു.

പ്രശ്നം: വിശ്വസിക്കാനാവാത്ത നെറ്റ്‌വർക്കുകൾ നെറ്റ്‌വർക്കുകൾ പരാജയപ്പെടാം. നിങ്ങളുടെ സെർവർ ഡാറ്റ പ്രോസസ്സ് ചെയ്യാൻ താമസമെടുച്ചേക്കാം. ഒരു DNS എറർ കാരണം നിങ്ങളുടെ 200 OK മറുപടി അയച്ചയാൾക്ക് ലഭിക്കാതിരിക്കാം.

ഒരു സർവീസിന് നിങ്ങളുടെ സ്ഥിരീകരണം ലഭിക്കാതെ വരുമ്പോൾ, അത് വീണ്ടും ശ്രമിക്കുന്നു (retry). അത് അതേ വെബ്ഹുക്ക് വീണ്ടും അയക്കുന്നു. നിങ്ങളുടെ കോഡ് എല്ലാ റിക്വസ്റ്റുകളും സ്വീകരിക്കുന്നുണ്ടെങ്കിൽ, അത് ഡ്യൂപ്ലിക്കേറ്റുകൾ ഉണ്ടാക്കുന്നു.

പരിഹാരം: ഐഡംപോറ്റൻസി (Idempotency) ഒരേപോലെയുള്ള ഒന്നിലധികം റിക്വസ്റ്റുകൾ അയച്ചാലും ഒരു സിംഗിൾ റിക്വസ്റ്റ് നൽകുന്ന അതേ ഫലം തന്നെ ലഭിക്കുന്നതിനെയാണ് ഐഡംപോറ്റൻസി എന്ന് പറയുന്നത്.

ഒരു ലിഫ്റ്റ് ബട്ടണിനെക്കുറിച്ച് ചിന്തിക്കുക. 5-ാം നിലയ്ക്കുള്ള ബട്ടൺ ഒരു തവണ അമർത്തിയാൽ ലിഫ്റ്റ് എങ്ങോട്ട് പോകണമെന്ന് അത് മനസ്സിലാക്കുന്നു. അത് പത്തുതവണ അമർത്തിയാലും ലിഫ്റ്റ് 50-ാം നിലയിലേക്ക് പോകില്ല. ഫലം മാറുന്നില്ല.

നിങ്ങളുടെ വെബ്ഹുക്കും ആ ബട്ടൺ പോലെ പ്രവർത്തിക്കണം.

ഇത് എങ്ങനെ പരിഹരിക്കാം സുരക്ഷിതമായ വെബ്ഹുക്കുകൾ നിർമ്മിക്കാൻ ഈ ഘട്ടങ്ങൾ പിന്തുടരുക:

  • ഇവന്റിന്റെ (event) യുണീക് ഐഡി കണ്ടെത്തുക.
  • മറ്റെന്തും ചെയ്യുന്നതിന് മുമ്പ് ആ ഐഡി നിങ്ങളുടെ ഡാറ്റാബേസിൽ ഉണ്ടോ എന്ന് പരിശോധിക്കുക.
  • ഐഡി ഉണ്ടെങ്കിൽ, അവിടെ നിർത്തുക. അയച്ചയാൾ വീണ്ടും ശ്രമിക്കുന്നത് ഒഴിവാക്കാൻ ഒരു 200 OK മറുപടി നൽകുക.
  • ഐഡി പുതിയതാണെങ്കിൽ, ഡാറ്റ പ്രോസസ്സ് ചെയ്യുക.
  • ഇവന്റ് ഐഡി ഉടൻ തന്നെ നിങ്ങളുടെ ഡാറ്റാബേസിൽ സേവ് ചെയ്യുക.

Node.js-ലെ ഉദാഹരണ ലോജിക്:

const eventId = req.body.event_id;

const existingEvent = await db.processedEvents.findUnique({
  where: { id: eventId }
});

if (existingEvent) {
  return res.status(200).send('Already processed');
}

await updateUserData(req.body.data);
await db.processedEvents.create({ data: { id: eventId } });

return res.status(200).send('Success');

അനുകൂലമായ സാഹചര്യങ്ങൾക്കായി സിസ്റ്റങ്ങൾ നിർമ്മിക്കുന്നത് എളുപ്പമാണ്. പരാജയങ്ങൾ സംഭവിക്കാവുന്ന സാഹചര്യങ്ങൾക്കായി സിസ്റ്റങ്ങൾ നിർമ്മിക്കുന്നതാണ് യഥാർത്ഥ എഞ്ചിനീയറിംഗ്.

റീട്രൈകളിൽ (retries) നിന്ന് ഡ്യൂപ്ലിക്കേറ്റ് ഡാറ്റ വന്ന അനുഭവം നിങ്ങൾക്കുണ്ടോ? നിങ്ങൾ ഐഡംപോറ്റൻസി എങ്ങനെയാണ് കൈകാര്യം ചെയ്യുന്നത്?

Source: https://dev.to/anubhavg23/the-hidden-trap-in-backend-tutorials-why-your-webhooks-are-creating-duplicate-data-and-how-to-fix-dba