แนวคิด CQRS
แยกคำสั่งออกจากคำค้นเพื่อให้โค้ดชัดเจน
แนวคิด CQRS เป็นบทเรียน C# Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C# Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
CQRS คืออะไร
CQRS ย่อมาจาก Command Query Responsibility Segregation แนวคิดนี้เรียบง่าย คือแยกโค้ดที่ เปลี่ยนแปลง สถานะ (คำสั่ง) ออกจากโค้ดที่ อ่าน สถานะ (คิวรี)
// Commands : change state, return little or nothing
// Queries : return data, change nothingคำสั่ง
คำสั่ง แสดงเจตนาที่จะเปลี่ยนแปลงระบบ เช่น สร้างคำสั่งซื้อ order หรือยกเลิกการสมัครสมาชิก คำสั่งจะตั้งชื่อในรูปคำกริยาเชิงคำสั่ง และโดยทั่วไปจะส่งคืนเพียงรหัสหรือไม่ส่งคืนอะไรเลย
public record CreateOrderCommand(int CustomerId, string[] Items);
public record CancelOrderCommand(int OrderId);คิวรี
คิวรี ขอข้อมูลโดยไม่มีผลข้างเคียง โดยจะตั้งชื่อตามข้อมูลที่ส่งคืนและบรรจุพารามิเตอร์ตัวกรองที่จำเป็น
public record GetOrderByIdQuery(int OrderId);
public record ListOrdersQuery(int CustomerId, int Page);เหตุใดจึงต้องแยกกัน
การอ่านและการเขียนมีความต้องการต่างกัน:
- การอ่านต้องการความรวดเร็ว โครงสร้างข้อมูลที่ไม่ทำให้เป็นรูปแบบปกติ และความเหมาะสมกับแคช
- การเขียนต้องการการตรวจสอบความถูกต้อง กฎทางธุรกิจ และความสอดคล้อง
การแยกทั้งสองส่วนทำให้แต่ละส่วนพัฒนาและปรับขนาดได้อย่างอิสระ
// Read side -> optimized projections / DTOs
// Write side -> domain rules / transactionsรูปแบบ Handler
คำสั่งหรือคิวรีแต่ละรายการจะถูกประมวลผลโดย handler โดยเฉพาะหนึ่งรายการ ข้อความหนึ่งรายการ handler หนึ่งตัว และความรับผิดชอบหนึ่งอย่าง ซึ่งช่วยให้คลาสมีขนาดเล็กและมุ่งเน้นชัดเจน
// CreateOrderCommand -> CreateOrderHandler
// GetOrderByIdQuery -> GetOrderByIdHandlerคอนโทรลเลอร์แบบบาง
เมื่อใช้ CQRS คอนโทรลเลอร์จะมีขนาดเล็กลง โดยสร้างข้อความแล้วส่งต่อ ส่วนตรรกะทั้งหมดจะอยู่ใน handler วิธีนี้ช่วยกำจัดคอนโทรลเลอร์ที่มีตรรกะหนาแน่นและปรับปรุงความสามารถในการทดสอบ
[HttpPost]
public async Task<IActionResult> Create(CreateOrderCommand cmd)
{
var id = await _sender.Send(cmd);
return CreatedAtAction(nameof(Get), new { id }, null);
}CQRS ไม่ใช่การจัดเก็บเหตุการณ์
ความเข้าใจผิดที่พบบ่อยคือ CQRS เป็นเพียงการแยกการอ่านและการเขียน ส่วน การจัดเก็บเหตุการณ์ (การจัดเก็บสถานะในรูปแบบบันทึกเหตุการณ์) เป็นรูปแบบที่แยกต่างหาก ซึ่งใช้ร่วมกับ CQRS ได้ดีแต่ไม่จำเป็นต้องใช้
// You can do CQRS with a plain single database.ที่เก็บข้อมูลเดียวกับแยกกัน
CQRS พื้นฐานใช้ฐานข้อมูลเดียวกันสำหรับทั้งสองฝั่ง การตั้งค่าขั้นสูงจะใช้ที่เก็บข้อมูลสำหรับการอ่านและการเขียนแยกกัน แล้วทำให้ข้อมูลสอดคล้องกัน โดยยอมรับความสอดคล้องในท้ายที่สุดเพื่อรองรับการปรับขนาด ควรเริ่มจากแบบง่าย
// Level 1: one DB, separate handlers (most apps)
// Level 2: separate read/write models
// Level 3: separate read/write databasesประโยชน์
CQRS มอบสิ่งต่อไปนี้ให้คุณ:
- handler ที่ชัดเจนและมีจุดประสงค์เดียว
- การทดสอบที่ง่ายขึ้น เพราะทดสอบ handler แต่ละตัวแยกกัน
- ตำแหน่งที่เหมาะสมตามธรรมชาติสำหรับประเด็นข้ามส่วน เช่น การตรวจสอบความถูกต้องและการบันทึกล็อก
- การปรับขนาดการอ่านและการเขียนได้อย่างอิสระ
// One class per use case = easy to find and testต้นทุน
CQRS เพิ่ม คลาสและการอ้อมผ่านส่วนประกอบต่าง ๆ มากขึ้น สำหรับแอป CRUD แบบง่ายอาจถือว่าซับซ้อนเกินความจำเป็น ควรนำไปใช้เมื่อมีตรรกะทางธุรกิจมากหรือโดเมนมีความซับซ้อน
// Trade-off: clarity & scale vs. boilerplateเริ่มใช้ MediatR
ไลบรารี MediatR ใช้รูปแบบตัวกลางภายในกระบวนการ เพื่อส่งต่อข้อความแต่ละรายการไปยัง handler ของรายการนั้น ทำให้คุณไม่ต้องเชื่อมต่อทุกอย่างด้วยตนเอง บทเรียนที่เหลือจะใช้ไลบรารีนี้
dotnet add package MediatRตรวจสอบความเข้าใจอย่างรวดเร็ว
ยืนยันความแตกต่างหลัก
สรุป
คุณได้เรียนรู้แนวคิดของ CQRS ดังนี้:
- แยก คำสั่ง (การเปลี่ยนแปลงสถานะ) ออกจาก คิวรี (การอ่านข้อมูล)
- ข้อความแต่ละรายการมี handler ที่มุ่งเน้นเพียงหนึ่งตัว ทำให้คอนโทรลเลอร์มีขนาดเล็ก
- CQRS เป็นอิสระจากการจัดเก็บเหตุการณ์และสามารถใช้ฐานข้อมูลเดียวได้
- MediatR ส่งต่อข้อความไปยัง handler
ถัดไป: คำสั่งและ handler ด้วย MediatR
คำถามที่พบบ่อย
บทเรียน “แนวคิด CQRS” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “แนวคิด CQRS” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C# Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C# Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “แนวคิด CQRS”
แยกคำสั่งออกจากคำค้นเพื่อให้โค้ดชัดเจน คุณปฏิบัติ C# Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C# Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C# Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “แนวคิด CQRS” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C# Academy นี้ได้ไหม
ได้ บทเรียน C# Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ