Message queues, Commands, Events, และ Queries
Event-driven architecture (EDA) คือ software architecture ที่ได้รับการยอมรับและเป็นที่นิยม มีการใช้งานทั่วโลกจนเป็นเรื่องปกติไปแล้ว เลยอยากสรุปความรู้พื้นฐานและรูปแบบต่างๆ ที่ใช้กับ EDA
รูปแบบหลักๆ ของ Event-driven architecture
- Event notifications
- Event-carried state transfer
- Event sourcing
Message queues, Commands, Events, and Queries
ก่อนที่จะเริ่มเรื่อง pattern ต่างๆ ของ EDA เรามาทำความรู้ message queues,commands, events และ queries กันก่อน
Message queues คือข้อมูลที่ใช้สื่อสารระหว่าง application เมื่อ state ของ application มีการเปลี่ยนเเปลง Producer(ผู้ผลิต) จะสร้าง message และ publish event ไปที่คิวโดยที่ไม่สนใจว่าจะมี consumer กำลัง listen อยู่หรือไม่ เป็นการทำงานรูปแบบ fire-and-forget ในขณะเดียวกัน Consumer (ผู้บริโภค) จะ subscribe events และหยิบเอา message ที่ตัวเองสนใจมาประมวลผลพร้อมกับลบออกจากคิว
Commands (คำสั่ง) คือการ request ให้ domain system ทำบางสิ่งบางอย่าง อาจจะมี response หรือไม่มีก็ได้ขึ้นอยู่กับ command นั่น สิ่งที่สำคัญ command ต้องเฉพาะเจาะจงมาก ๆ ว่าปลายทางคือใคร อยากให้ทำอะไร เช่น ระบบ order system เราต้องการสร้าง order เราจะบอก order system ว่า นี่คือ order และมีข้อมูลตามนี้ สร้างให้หน่อย ซึ่ง order system จะทำหรือปฏิเสธก็ได้ ตามรูปด้านล่าง command นี้มีชื่อว่า create order
Events (เหตุการณ์) คือ เมื่อมีการเปลี่ยนเเปลง state ของ domain system เราจะ publish สถานะปัจจุบันออกไป เพื่อให้ใครก็ตามที่สนใจ event นี้ ได้รับข้อมูลล่าสุด ดังนั่น event ที่ถูก publish จะไม่สามารถแก้ไขเปลี่ยนแปลงหรือ undo สิ่งเดียวที่ทำได้คือการ publish event เพื่อชดเชย ปกติเราจะตั้งชื่อ event เป็นคำกริยา past tense verb เช่น หลังจาก create order เสร็จแล้ว จะเกิด event ที่ชื่อว่า order created
Queries คือ การ request ไปที่ domain system เพื่อค้นหาบางสิ่ง มีความแตกต่างจาก events หรือ commands เพราะว่า queries จะไม่มีผลต่อ state ของ domain system เช่น การดึงข้อมูล order ล่าสุด
Differences ระหว่าง commands, events, และ querie
Commands ทำงานแบบ synchronous เช่น Rest API เพราะว่าต้องการทราบทันทีว่าคำขอที่ส่งไปได้ดำเนินการแล้วหรือยัง เพื่อใช้ในการตัดสินใจว่าจะให้ application ทำงานต่อไปยังไง
Example: createOrder(order);
//return กลับไปเสมอ ไม่ว่าจะสำเร็จหรือ error
Events ทำงานแบบ asynchronous ผ่าน queues (In-memory, RabbitMQ, Kafka) เพราะว่า Event doesn’t have an objective. หมายความว่าหลังจากที่บอก remote system ว่ามี event นี้เกิดขึ้นแล้ว เราไม่ได้คาดหวัง response ใดๆ ดังนั่น remote system สามารถยอมรับ ปฏิเสธ หรือเลือกที่จะตอบกลับก็ได้ ไม่มีผลต่อ event นั่น
Example: OrderCreated(order);
OrdersDetailsUpdated(order);
Queries การทำงานแบบ synchronous เพื่อค้นหาข้อมูลและได้รับ response กลับมาเสมอ จะทำงานบน protocol เช่น HTTP หรือ gRPC
Example: getOrder((ID = 112));
//return Order(112,...);