Концепции CQRS
Разделяйте команды и запросы для ясности.
«Концепции CQRS» — бесплатный урок C# Academy на CoddyKit. Это урок 1 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения C# Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс C# Academy содержит 4 уроков всего.
Что такое CQRS
CQRS — это сокращение от разделения ответственности команд и запросов. Идея проста: отделить код, который изменяет состояние (команды), от кода, который читает состояние (запросы).
// Commands : change state, return little or nothing
// Queries : return data, change nothingКоманды
Команда выражает намерение изменить систему — создать заказ или отменить подписку. Она формулируется в повелительной форме и обычно возвращает только идентификатор либо ничего.
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, одна ответственность — это помогает сохранять классы небольшими и целенаправленными.
// 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 предоставляет следующие возможности:
- Понятные обработчики, каждый из которых выполняет одну задачу.
- Более простое тестирование — каждый обработчик тестируется изолированно.
- Естественное место для сквозной логики (проверки, журналирования).
- Независимое масштабирование чтения и записи.
// One class per use case = easy to find and testЗатраты
CQRS добавляет больше классов и косвенных связей. Для простого приложения с базовыми операциями создания, чтения, обновления и удаления это может быть избыточно. Применяйте его там, где бизнес-логика насыщенна или предметная область сложна.
// Trade-off: clarity & scale vs. boilerplateЗнакомство с MediatR
Библиотека MediatR реализует шаблон посредника внутри процесса: он отправляет каждое сообщение соответствующему handler, поэтому Вам не приходится связывать их вручную. В остальной части курса используется именно этот подход.
dotnet add package MediatRБыстрая проверка
Проверьте, понимаете ли Вы основное различие.
Итоги
Вы изучили концепции CQRS:
- Разделяйте команды (изменение состояния) и запросы (чтение).
- У каждого сообщения есть один целенаправленный handler, благодаря чему контроллеры остаются тонкими.
- CQRS не зависит от предметной фиксации событий и может использовать одну базу данных.
- MediatR отправляет сообщения обработчикам.
Далее: команды и обработчики с MediatR.
Часто задаваемые вопросы
Урок «Концепции CQRS» бесплатный?
Да — полный текст урока «Концепции CQRS» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс C# Academy, подпишись на CoddyKit PRO. Курс C# Academy содержит 4 уроков всего.
Чему я научусь в уроке «Концепции CQRS»?
Разделяйте команды и запросы для ясности. Ты практикуешь C# Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать C# Academy?
Предыдущий опыт не требуется. C# Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 1 из 4.
Сколько времени занимает урок «Концепции CQRS»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке C# Academy?
Да. Каждый урок C# Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.