ตั้งแต่ทฤษฎีถึงการใช้งานจริงของ Event Sourcing: สร้างบริการ Remote Config ด้วย NestJS
(borntodare.me)บทนำ
ผมเคยได้ความช่วยเหลืออย่างมากในการทำความเข้าใจ Event Sourcing จากการบรรยายของคุณวอนจีฮยอกเกี่ยวกับ Event Sourcing ในงาน Danggeun Server Meetup บทความนี้จึงสรุปแนวคิดพื้นฐานของ Event Sourcing และลองสร้างบริการคอนฟิกอย่างง่ายบนพื้นฐานของ NestJS, TypeScript และ MongoDB จากเนื้อหาในการบรรยาย
- ต้นฉบับ: สร้างแพลตฟอร์มภายในองค์กรที่ขยายต่อได้ด้วย Event Sourcing | Danggeun SERVER Meetup ครั้งที่ 2
- ซอร์สโค้ดตัวอย่างของบริการคอนฟิกแบบ Event Sourcing
แนวคิดพื้นฐานของ Event Sourcing
- แตกต่างจากแนวทาง CRUD แบบเดิม โดยจะบันทึกการเปลี่ยนแปลงสถานะทั้งหมดเป็นอีเวนต์แบบ immutable ทำให้ตรวจสอบย้อนหลังและ rollback ได้ง่าย
- เหมือนสมุดบัญชีที่บันทึกรายการธุรกรรมทั้งหมดตามลำดับ จึงสามารถสร้างสถานะปัจจุบันขึ้นมาใหม่ได้ทุกเมื่อ
องค์ประกอบหลัก
- อีเวนต์
- ประกอบด้วย ID เฉพาะ เวลาที่สร้าง ประเภทอีเวนต์ ข้อมูลผู้ใช้ และเนื้อหา (body) พร้อมรับประกันความเป็น immutable และความสมบูรณ์ในตัวเอง
- สเตต
- สถานะสุดท้ายที่คำนวณได้จากการ replay อีเวนต์ทั้งหมด (สามารถใช้ snapshot หรือ cache ได้เมื่อจำเป็น)
- รีดิวเซอร์
- ฟังก์ชันบริสุทธิ์ที่รับสถานะก่อนหน้าและอีเวนต์มาเป็นอินพุต แล้วคำนวณสถานะใหม่โดยคงความเป็น immutable ไว้
- เอนทิตี
- รวบรวมอีเวนต์ที่เกี่ยวข้องมาจัดการเป็นออบเจ็กต์เดียว ทำให้เรียกดูประวัติการเปลี่ยนแปลงของเอนทิตีเฉพาะได้อย่างมีประสิทธิภาพ
ตัวอย่างการใช้งานและโครงสร้าง
- การตั้งค่าสภาพแวดล้อมพื้นฐาน: ใช้ NestJS เพื่อรันแอปพลิเคชัน
- การกำหนดเอนทิตีและอีเวนต์
- ใช้ TypeScript interface และ MongoDB schema เพื่อกำหนดอีเวนต์หลากหลายประเภทอย่างชัดเจน (เช่น การสร้างคอนฟิก การเพิ่ม/ลบพารามิเตอร์) และกำหนดออบเจ็กต์สถานะ
- การเขียนรีดิวเซอร์:
- เขียนฟังก์ชันบริสุทธิ์ที่อัปเดตสถานะตามประเภทอีเวนต์ เพื่อ replay ลำดับอีเวนต์และคำนวณสถานะสุดท้าย
- API endpoint และ service layer
- สร้าง REST API ที่รองรับการสร้างคอนฟิก การเรียกดู การเพิ่ม/ลบพารามิเตอร์
- ใช้แพตเทิร์น dispatch-commit เพื่อจัดการการเผยแพร่อีเวนต์ การคำนวณสถานะ และการบันทึกอีเวนต์ตามลำดับ
การต่อยอดเพิ่มเติมและการเชื่อมต่อกับระบบภายนอก
- generic interface
- ออกแบบ event repository ที่นำกลับมาใช้ซ้ำได้เพื่อลดโค้ดซ้ำและเพิ่ม type safety
- event handler
- เชื่อมต่อกับระบบภายนอกอย่าง Slack เพื่อทำงานเพิ่มเติม เช่น ส่งการแจ้งเตือนเมื่อเกิดอีเวนต์
- กลยุทธ์การปรับแต่งประสิทธิภาพ
- snapshot: บันทึกสถานะ ณ จุดเวลาหนึ่ง แล้วนำอีเวนต์หลังจากนั้นมาใช้ต่อ เพื่อลดต้นทุนในการ replay อีเวนต์ทั้งหมด
- caching: ใช้ in-memory cache หรือ Redis เพื่อให้บริการสถานะของเอนทิตีที่ถูกเรียกดูบ่อยได้รวดเร็ว
บทสรุป
- Event Sourcing เป็นสถาปัตยกรรมที่ทรงพลังซึ่งบันทึกประวัติการเปลี่ยนแปลงทั้งหมดอย่างชัดเจน ช่วยเพิ่มความน่าเชื่อถือและความสามารถในการบำรุงรักษา
- ควรค่อย ๆ นำมาใช้ให้เหมาะกับโดเมน พร้อมใช้กลยุทธ์อย่าง snapshot และ caching เพื่อคงประสิทธิภาพของระบบ และต้องพิจารณา learning curve อย่างรอบคอบก่อนนำไปใช้
1 ความคิดเห็น
เยี่ยมเลย! ^0^