กับดักในบทเรียน Backend

บทเรียนต่างๆ มักจะแสดงขั้นตอนที่ดูเรียบง่าย รับ webhook อัปเดตฐานข้อมูล ส่งค่า 200 OK กลับไป

โค้ดของคุณทำงานได้ดีในการทดสอบ เมื่อคุณนำขึ้น production คุณกลับพบข้อมูลซ้ำซ้อนในฐานข้อมูล ผู้ใช้ได้รับเครดิตซ้ำสองครั้ง และข้อมูลเริ่มสะสมจนล้น

บทเรียนเหล่านี้มักมองข้ามความเป็นจริงเรื่องความล้มเหลวของเครือข่าย (network failure)

ปัญหา: เครือข่ายที่ไม่เสถียร เครือข่ายสามารถล้มเหลวได้ เซิร์ฟเวอร์ของคุณอาจประมวลผลข้อมูลช้า หรือข้อผิดพลาดของ DNS อาจทำให้การตอบกลับ 200 OK ของคุณส่งไปไม่ถึงผู้ส่ง

เมื่อบริการหนึ่งไม่ได้รับการยืนยันจากคุณ มันจะพยายามใหม่ (retry) โดยการส่ง webhook เดิมซ้ำมาอีกครั้ง หากโค้ดของคุณยอมรับทุกคำขอ คุณก็จะสร้างข้อมูลซ้ำซ้อนขึ้นมา

วิธีแก้ปัญหา: Idempotency Idempotency หมายถึงการที่การส่งคำขอที่เหมือนกันหลายๆ ครั้ง ให้ผลลัพธ์เหมือนกับการส่งคำขอเพียงครั้งเดียว

ลองนึกถึงปุ่มกดลิฟต์ การกดปุ่มชั้น 5 เพียงครั้งเดียวเป็นการบอกลิฟต์ว่าต้องไปที่ไหน การกดปุ่มเดิมสิบครั้งก็ไม่ได้ทำให้ลิฟต์วิ่งไปถึงชั้น 50 ผลลัพธ์ยังคงเหมือนเดิม

Webhook ของคุณต้องทำงานเหมือนกับปุ่มนั้น

วิธีแก้ไข ทำตามขั้นตอนเหล่านี้เพื่อสร้าง webhook ที่ปลอดภัย:

  • ค้นหา ID ที่ไม่ซ้ำกัน (unique ID) ของเหตุการณ์นั้น
  • ตรวจสอบในฐานข้อมูลว่ามี ID นั้นอยู่แล้วหรือไม่ก่อนที่จะเริ่มทำอะไร
  • หากพบ ID นั้นอยู่แล้ว ให้หยุดทำงาน และส่งค่า 200 OK กลับไป เพื่อให้ผู้ส่งหยุดพยายามส่งซ้ำ
  • หากเป็น ID ใหม่ ให้เริ่มประมวลผลข้อมูล
  • บันทึก ID ของเหตุการณ์ลงในฐานข้อมูลของคุณทันที

ตัวอย่างตรรกะใน 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');

การสร้างระบบสำหรับสภาวะที่สมบูรณ์แบบนั้นเป็นเรื่องง่าย แต่การสร้างระบบเพื่อรองรับความล้มเหลวต่างหากคือวิศวกรรมที่แท้จริง

คุณเคยเจอปัญหาข้อมูลซ้ำจากการ retry บ้างไหม? และคุณจัดการกับ idempotency อย่างไร?

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