CQRS: روشنکردن مرزهای برنامه
در CQRS، تغییر وضعیت برنامه و خواندن اطلاعات از دو مسیر جدا انجام میشود. فرمان وضعیت را تغییر میدهد؛ درخواست خواندن فقط اطلاعات را برمیگرداند. برای این جداسازی لازم نیست سرویس جدا، پایگاه دادهی دوم یا گذرگاه رویداد داشته باشیم.
اگر فقط قرار است یک مقدار ساده تغییر کند، همان بهروزرسانی معمولی کافی است. اما اگر یک بهروزرسانی کلی اقدام مورد نظر کاربر، قواعد آن، مجوز لازم یا پیامد تغییر را روشن نکند، تعریف یک فرمان مشخص کمک میکند خواستهی کاربر روشن باشد. برای خواندن هم میتوان داده را متناسب با نیاز فراخواننده آماده کرد، بیآنکه وضعیت برنامه تغییر کند.
مسیرهای خواندن و نوشتن میتوانند در یک برنامه و یک پایگاه داده بمانند. اگر نیازهای خواندن از نظر شکل داده یا حجم درخواستها با نیازهای نوشتن فرق کند، مدل یا مخزن خواندن جدا میتواند مفید باشد. اما این جداسازی همگامسازی دادهها، احتمال خواندن دادهی قدیمی، مدیریت بازیابی و مسئولیت عملیاتی تازهای بههمراه دارد. فقط وقتی سراغش بروید که فایدهاش هزینهاش را توجیه کند.
- وقتی CRUD دیگر زبان مناسبی برای مسئله نیست
برای تغییر نام نمایشی یا یک تنظیم ساده، CRUD کاملاً کافی است. مسئله از جایی شروع میشود که تغییر چند فیلد، یک تصمیم کسبوکار با مجوز، دلیل و پیامدهای خودش را پنهان میکند. این نوشته نشان میدهد چرا گاهی باید بهجای فرستادن یک DTO تغییرکرده، خود عمل را نام ببریم. CQS و CQRS برای همین نقطهاند، نه برای پیچیده کردن هر update معمولی.
- CQS و commandها: کاری کنید برنامه هدف کاربر را بفهمد
یک DTO تغییرکرده فقط میگوید وضعیت چه شده است، نه اینکه کاربر دقیقاً چه کاری خواسته. وقتی تغییر به مجوز، دلیل یا قانونهای دیگر گره میخورد، این تفاوت مهم میشود. commandی با نام روشن، مثل `DeactivateInventoryItem`، هدف کاربر را مستقیم به برنامه میرساند. بعد اعتبارسنجی، مجوزدهی و قواعد همان عمل در یک نقطه میمانند.
- CQRS حداقلی: مسیرهای کد را جدا کنید، یک برنامه و یک دیتابیس نگه دارید
CQRS لازم نیست از همان روز اول با دو دیتابیس و چند سرویس شروع شود. میتوان command و query را در همان برنامه و همان دیتابیس جدا کرد، چون کارشان واقعاً یکی نیست. مسیر command از تغییر محافظت میکند و مسیر query پاسخ مناسب خواندن را میسازد. این انتخاب تراکنش و خواندن فوری را نگه میدارد، اما مقیاسپذیری مستقل خواندن را به دست نمیدهد.
- CQRS با مخزن خواندن جدا: projectionهای مفید و تضمینهای تازه
مخزن خواندن جدا به مدل query اجازه میدهد داده را برای یک صفحه یا گزارش شکل دهد، نه برای نیازهای مدل نوشتن. این کار میتواند joinهای پرهزینه را کم کند و ظرفیت خواندن را مستقل بالا ببرد. در عوض، یک مسئلهی همگامسازی به وجود میآید. ممکن است دادهی خواندنی قدیمی باشد، projection باید بتواند امن بازیابی شود و برنامه باید روشن کند کاربر پس از ارسال یک command چه چیزی میبیند.