CodeShot

Command در مقابل Query

Command در الگوی CQRS عملیاتی است که وضعیت سیستم را تغییر می‌دهد (مثل ایجاد یا حذف) و معمولاً مقدار قابل توجهی برنمی‌گرداند، در حالی که Query عملیاتی است که فقط داده می‌خواند و هیچ تغییری در وضعیت سیستم ایجاد نمی‌کند؛ جدا کردن این دو مسیر اجازه می‌دهد هرکدام مستقل بهینه‌سازی و مقیاس‌دهی شوند.

ویژگیCommandQuery
تغییر وضعیتبلهخیر
مقدار بازگشتیحداقلیداده کامل درخواستی
قابلیت کش کردنخیربله

کِی از Command استفاده کنیم؟

وقتی عملیات باعث تغییر داده می‌شود، مثل «ثبت سفارش» یا «به‌روزرسانی پروفایل کاربر».

کِی از Query استفاده کنیم؟

وقتی عملیات فقط برای نمایش یا خواندن داده است، مثل «لیست سفارش‌های کاربر» یا «جزئیات محصول».

مثال Command

public record CreateOrderCommand(int UserId, List<Item> Items)
    : IRequest<Guid>;
// نتیجه: فقط شناسه سفارش جدید

مثال Query

public record GetOrderByIdQuery(Guid OrderId)
    : IRequest<OrderDto>;
// نتیجه: داده کامل سفارش، بدون تغییر وضعیت

اشتباه رایج

اشتباه رایج نوشتن یک Query که ضمن خواندن داده، به‌طور جانبی هم چیزی را تغییر می‌دهد (مثل افزایش شمارنده بازدید در همان متد Get) است؛ این کار مرز Command/Query را مخدوش می‌کند و مزایای CQRS مثل کش‌پذیری امن Query ها را از بین می‌برد.

جمع‌بندی

هر عملیات باید یا Command (تغییر وضعیت، بدون بازگشت داده اضافی) باشد یا Query (فقط خواندن، بدون عارضه جانبی)؛ هرگز این دو را در یک متد مخلوط نکنید.