Введение
CQRS (Command Query Responsibility Segregation – разделение ответственности команд и запросов) – архитектурный паттерн, предложенный Грегом Янгом, при котором операции изменения состояния (команды) и операции чтения (запросы) используют раздельные модели данных и раздельные интерфейсы.
Основной принцип: метод либо изменяет состояние, либо возвращает данные – но не то и другое одновременно. Это развитие принципа CQS (Command/Query Separation), сформулированного Бертраном Мейером в книге «Object-Oriented Software Construction» (1988).
История и контекст
CQS как принцип уровня методов известен с 1988 года. CQRS как архитектурный паттерн популяризировал Грег Янг в 2010 году, применив разделение на уровне всей системы – с отдельными write-моделями и read-моделями, потенциально хранящимися в разных базах данных. Мартин Фаулер описал CQRS в своём блоге как паттерн, мощный в сочетании с Event Sourcing, но предупредил о рисках избыточной сложности при неуместном применении.
Как это работает
Write side (команды):
- Принимает команды (CreateOrder, UpdatePayment);
- Валидирует и выполняет бизнес-логику через доменную модель;
- Сохраняет состояние (или события, если используется Event Sourcing);
- Оптимизирована под целостность данных (нормализация, транзакции).
Read side (запросы):
- Предоставляет проекции данных, оптимизированные под UI;
- Денормализованные таблицы или документы для быстрого чтения;
- Может использовать другую БД (Redis, Elasticsearch, read-реплику PostgreSQL);
- Обновляется асинхронно через события от write side.
Между сторонами – eventual consistency: после команды read-модель обновляется не мгновенно, а после обработки соответствующего события.
Где применяется
- Системы с высоким соотношением чтения к записи (e-commerce, аналитика);
- Микросервисные системы с Event Sourcing;
- DDD-приложения с богатой доменной моделью;
- Финтех-системы: транзакции на write side, отчёты на read side;
- Корпоративные порталы с комплексными представлениями данных.
Преимущества и ограничения
Преимущества: независимое масштабирование читающих и пишущих компонентов; раздельная оптимизация моделей; упрощение доменной модели на write side; чистое разделение ответственности.
Ограничения: значительное увеличение сложности системы; eventual consistency требует специальной обработки на клиенте; синхронизация read/write моделей добавляет инфраструктурные компоненты. Не рекомендуется для простых CRUD-сценариев.
Связь с другими понятиями
CQRS неразрывно связан с Event Sourcing: write side сохраняет события, read side строит проекции из этих событий. Domain-Driven Design – естественная среда применения CQRS: Aggregate на write side, Read Model на read side. Event-driven Architecture обеспечивает асинхронную синхронизацию между сторонами. В контексте микросервисов CQRS помогает строить масштабируемые сервисы с отдельными хранилищами.