私の知る限り、CQRSの背後にある大きなアイデアは、コマンドとクエリを処理するための2つの異なるデータモデルを持つことです。これらは「書き込みモデル」および「読み取りモデル」と呼ばれます。
Twitterアプリケーションのクローンの例を考えてみましょう。コマンドは次のとおりです。
- ユーザーは自分で登録できます。
CreateUserCommand(string username)放出するUserCreatedEvent - ユーザーは他のユーザーをフォローできます。
FollowUserCommand(int userAId, int userBId)放出するUserFollowedEvent - ユーザーは投稿を作成できます。
CreatePostCommand(int userId, string text)放出するPostCreatedEvent
上記では「イベント」という用語を使用していますが、「イベントソース」イベントを意味するものではありません。読み取りモデルの更新をトリガーする信号を意味します。イベントストアはありませんが、これまではCQRS自体に集中したいと考えています。
クエリは次のとおりです。
- ユーザーは投稿のリストを見る必要があります。
GetPostsQuery(int userId) - ユーザーは、フォロワーのリストを見る必要があります。
GetFollowersQuery(int userId) - ユーザーは、フォローしているユーザーのリストを見る必要があります。
GetFollowedUsersQuery(int userId) - ユーザーは、「フレンドフィード」-すべての友達のアクティビティのログ(「友達のジョンが新しい投稿を作成しました」)を表示する必要があります。
GetFriedFeedRecordsQuery(int userId)
処理CreateUserCommandするには、そのようなユーザーが既に存在するかどうかを知る必要があります。したがって、この時点で、自分の書き込みモデルにはすべてのユーザーのリストが必要であることを知っています。
処理FollowUserCommandするには、userAがすでにuserBをフォローしているかどうかを知る必要があります。この時点で、書き込みモデルにすべてのユーザーフォローユーザー接続のリストが必要です。
そして最後に、処理するCreatePostCommandために他に何も必要ないと思います。なぜなら、私にはのようなコマンドがないからUpdatePostCommandです。それらがある場合、投稿が存在することを確認する必要があるため、すべての投稿のリストが必要になります。しかし、この要件がないため、すべての投稿を追跡する必要はありません。
質問#1:実際に使用する「モデルの書き込み」という用語を使用するのは実際に正しいですか?または、ESの場合、「書き込みモデル」は常に「イベントストア」を表しますか?もしそうなら、コマンドを処理する必要があるデータとクエリを処理する必要があるデータの間に何らかの分離がありますか?
を処理GetPostsQueryするには、すべての投稿のリストが必要です。つまり、読み取りモデルにはすべての投稿のリストが必要です。私はを聞いてこのモデルを維持しPostCreatedEventます。
GetFollowersQueryとの両方を処理するには、GetFollowedUsersQueryユーザー間のすべての接続のリストが必要です。このモデルを維持するために耳を傾けるつもりですUserFollowedEvent。ここに質問#2があります:書き込みモデルの接続リストをここで使用しても実質上問題ありませんか?または、将来、書き込みモデルよりも詳細な情報が必要になる可能性があるため、個別の読み取りモデルを作成する必要がありますか?
最後に、処理するGetFriendFeedRecordsQueryには次のことが必要です。
- 聞く
UserFollowedEvent - 聞く
PostCreatedEvent - どのユーザーがどの他のユーザーをフォローしているかを知る
ユーザーAがユーザーBをフォローし、ユーザーBがユーザーCをフォローし始めると、次のレコードが表示されます。
- ユーザーAの場合:「友達ユーザーBはユーザーCのフォローを開始しました」
- ユーザーBの場合:「ユーザーCのフォローを開始しました」
- ユーザーCの場合:「ユーザーBがあなたをフォローしています」
ここだ質問#3:私は接続のリストを取得するために使用すべきかのモデル?書き込みモデルを使用する必要がありますか?読み取りモデルを使用する必要があります- GetFollowersQuery/ GetFollowedUsersQuery?または、GetFriendFeedRecordsQueryモデル自体UserFollowedEventにすべての接続の独自のリストを処理させ、維持させる必要がありますか?