CQRSはRead ModelとWrite Modelの分離でありCommand BusやEvent Sourcingの同義語ではない
CQRS (Command Query Responsibility Segregation) は、Applicationの更新側モデルと参照側モデルを分ける設計パターンである。Command Bus、message broker、Event Sourcingを必須要素とするものではない。
Microsoft Azure Architecture Centerの現行CQRS patternは、最も基本的な実装として同じdata storeを使いながらread/write logicとmodelだけを分離する構成も示している。必要になればread側をmaterialized viewへ最適化し、write側と別storeへ分離できるが、その場合はeventual consistencyなど追加の複雑性を引き受ける。
CQRSが有効になりやすいのは、readとwriteで要求が大きく異なる場合である。例えばwrite側ではDomain invariantと細粒度authorizationを重視し、read側では全文検索、集計、projection、paginationに特化したmodelを持ちたい場合がある。Search Authorizationは検索集合と認可集合のIntersection問題になる のように検索集合と認可集合を効率よくintersectionするため、read-optimized projectionやauthorization indexを持つ構成とも接続しうる。
一方、Martin FowlerはCQRSについて、多くのsystemでは複雑性を増やす危険なpatternになりうると警告している。単純なCRUDや、read/writeで同じmodelが自然に使えるApplicationへ導入すると、同期、重複model、eventual consistency、debuggingなどの負担だけが増える。
またCommandはHTTP Requestではなく状態変更の意図を表す を使うことやCommand BusはOperation dispatchの選択肢でありArchitectureの前提ではない を置くことはCQRS採用を意味しない。逆にCQRSでもwrite handlerを直接呼び、read query serviceを直接呼ぶだけの構成は成立する。
Vertical SliceはLayerではなくUse Caseの変更軸に沿ってコードをまとめる と組み合わせる場合も、Command sliceとQuery sliceを分けやすいというだけで必須の組み合わせではない。まず単一modelで保ち、read/writeの変化理由や性能要求が実際に分かれた時点で分離する方がLocalization Costを抑えやすい。