Кожен додаток — унікальний, і заслуговує на особливий підхід. На щастя, у розробників додатків є чудовий вибір архітектурних стилів та принципів, які можна застосувати та навіть ідеально поєднати між собою. Нещодавно ми вам розповідали про архітектуру мікросервісів у розробці додатків. Сьогодні буде не менш цікава тема — принцип розділення відповідальності між командами і запитами (Command Query Responsibility Segregation або CQRS). Що ж, давайте просто зараз розділимо нашу відповідальність: ми розповідаємо, а ви — читаєте і насолоджуєтесь.
Принцип CQRS (Command Query Responsibility Segregation): у чому він полягає
Саме розділена відповідальність лежить в основі CQRS — принципу, що був запропонований Грегом Яном і Уді Даханом. CQRS черпає свою суть з іншого принципу — CQS (Command Query Separation), автором якого є Бертран Мейер. Будь-який метод повинен або змінювати стан об'єкту, або вертати результат — але не те і інше одночасно. Так Бертран Мейер описав основну ідею CQS.
Принцип розділення відповідальності між командами і запитами (CQRS) також базується на цій філософії. CQRS — архітектурний шаблон, який передбачає розділення додатку на дві окремі моделі даних. Одна з них відповідає за оновлення даних (операції з написання), інша — за відображення даних (операції зі зчитування). Згідно з термінологією вищезгаданого CQS, ці операції відомі як команди і запити.
Команди VS запити: строгий розподіл ролей
Кожна операція — це або команда, або запит, і не може бути поєднанням обох.
- Команда (також відома як модифікатор) вносить зміни в систему, але не повертає дані.
- Запит, навпаки, отримує та відображає дані з системи, але не може їх змінювати.
Запити мають тип “return”, а команди не вертають значення, тобто є “void”. Команди і запити не можуть обмінюватись ролями. Таким чином, одна частина вашого додатку сконцентрована виключно на обробці команд, а інша — суто на відображенні даних.
Використання однієї або різних баз даних
Працюючи за принципом CQRS, ви можете використовувати одну базу даних для обох моделей свого додатку. Користувач дає команду, згідно з якою модель, відповідальна за оновлення інформації, вносить зміни до бази даних, а модель, що працює зі зчитуванням інформації, робить запит до бази даних і виводить результат.
Однак, популярнішим рішенням, яке повністю відображає філософію CQRS, є робота з окремими базами даних. Команди надсилаються до однієї бази, дані там обробляються і передаються в іншу базу, яка відповідно оновлюється. Цей підхід дозволяє підвищити продуктивність, масштабованість та безпеку.
Переваги CQRS
Одна з найбільших переваг CQRS — можливість розширювати та оптимізувати кожну з сторін додатку незалежно одна від одної. Ви можете створити найкращі умови для кожної з них, ніяк не зачепивши “інтересів” іншої. Це підвищує продуктивність та дає вам більший простір для внесення змін у майбутньому.
Розділення відповідальності можливе не тільки для програмного забезпечення, а й для людей, які працюють над його створенням. Дуже ефективним рішенням може бути розподіл роботи між окремими командами розробників. Наприклад, більш досвідчена команда могла б відповідати за “командну” частину, що містить складні алгоритми обробки інформації, а менш досвідчена — працювати з частиною виведення даних, без потреби заглиблюватись в усі процеси першої.
CQRS також дасть вам можливість створити інтерактивний, задачо-орієнтований користувацький інтерфейс, в якому основна увага приділяється намірам користувача.
Command Query Responsibility Segregation чудово поєднується з іншим підходом, що називається Event Sourcing. Його суть — в зберіганні усіх даних системи у вигляді подій.
Хоча принцип розділення команд і запитів може творити дива, його потрібно використовувати обережно і тільки коли це використання виправдане. Адже він повинен позбавляти додаток надмірної складності, а не додавати її.
CQRS — це відхід від традиційного принципу CRUD, який передбачає єдину модель для створення, зчитування, оновлення і видалення (creating, reading, updating and deleting) інформації. Для багатьох систем CRUD є абсолютно достатнім, тож у CQRS немає потреби.
Деякі випадки, в яких чудово підійде CQRS:
- додатки з нерівним навантаженням, наприклад, з великою кількістю запитів і малою кількістю оновлень;
- інші випадки, коли кожна із сторін додатку потребує окремого налаштування;
- складні домени;
- системи зі складною бізнес-логікою;
- складна обробка даних;
- мінливі бізнес-умови, очікувані зміни в додатку.
Завжди існує ідеальне рішення для кожного додатку — Command Query Responsibility Segregation (CQRS) чи інше! Але є один випадок, в якому відповідальність точно можна не розділяти — якщо ви повністю доручите створення свого супер-додатку нашій досвідченій команді ;)