はじめに
前々回、前回とあまりに走り書きすぎたので一応解説いれておこう編です。
そもそもcqrs+esってなんじゃいな
CQRSとは
CQRS(Command Query Responsibility Segregation)はコマンド/クエリ責務分離と言われるもので、コマンド層とクエリ層に責務を分けることで、通常起こりがちなアプリ~データベース間等のインピーダンスミスマッチを吸収しちゃおうという考えだと個人的には理解してます。
CQRSをDDD(ドメイン駆動設計)に持ち込むことで、コマンド層ではドメインに集中した開発、クエリ層ではユーザーインターフェースに集中した開発が可能となり(関心の分離)、ごっちゃ煮感溢れるインフラ層もそれぞれに分割することが可能となります。
ESとは
ES(Event Sourcing)は従来型の常に最新の状態をRDB等に保存する方法とは異なり、そのオブジェクトに発生したイベントを積み上げ型に保存する方法です(DDDの場合、ドメインになるはず)。オブジェクトに起こったことは全て記録し、オブジェクトの状態は常にその積み上げの結果となります。
DDD+CQRSにおいてはコマンド側でドメインに変化が起こった場合、それを何らかの方法でクエリ側に通知する必要があります。ESであればドメインの変化を全て網羅しているのでクエリ側もドメインで起こった出来事をイベントをたどることで全て知ることができるようになります。それにより自身のDTOを更新するかどうかも自身で判断できます。
今回の設計
上記を踏まえて・・・
前回、アクターシステムがって突然出しましたが、CQRSのScala(or Java)向けフレームワークでAkkaというものがありまして、それから派生したというか分離した?golangで書かれたProto.Actorというものをヒントにして作った関係でこんな感じになりました。Proto.Actorではアクター自身がprotocol-bufferを使ってやり取りする感じなんですが、今回は使わず上辺だけ真似ています(互いのアクターに依存する部分が出たりしたので)。
コマンド側
アクター(TodoActor)がドメイン(Todo)に対する実権を握っています。プレゼン層からコマンドを受け付け、イベントを生成し、ドメインに流し、永続化機構(Persistence)に保存した後でメッセージング機構(MessagingPublisher)へイベントの発生を通知します。
アクター以外はドメインのことは知りませんし、関係ありませんって感じです。
クエリ側
こちらもアクター(TodoActor)がDTO(TodoQuery)に対する実権を持ちます。メッセージング機構(MessagingConsumer)から通知を受けると永続化機構(PersistenceQuery)にイベントを問合せ、DTOに適用し、永続化します。
プレゼン層は当然それらのことに関知せず、DTOの最新の状態のみが関心毎になります。
おわりに
解説になってない気もする。