イベントソースに関するFowlerまたは同様のソースの記事を読むと、次のようなものが脳内にあるかもしれません。
![画像](https://habrastorage.org/getpro/habr/post_images/758/f8d/8c1/758f8d8c1b3249530f9eb8ef9284efd0.png)
このアプローチの一般的な考え方は、ユーザー(または他の外部システム)がコマンドを生成し、受信したイベントをイベントストアに追加し、データベース内の「世界の状態」、ユーザーが要求するデータを更新することで処理します。
このアプローチはシンプルで美しいように見えます。 イベントを「再生」するのに十分なデータがあり、世界の状態に関するデータを要求する場所があり、実績のあるデータベースを使用できます。 一方で、イベントソーシングの概念とは少し違うものが欲しかったことに気付きました。 将来の予測を避けたかったのですが、更新された状態を読み取り専用データベースに書き込む必要があるため、このモデルはどういうわけかあまり適切ではありませんでした。
私たちが行動の意図と関連するすべてのデータを収集するというまさにその考えは、常に過去を調べて、この情報の収集中にあまり有用ではなかった情報を使用できるという考えにつながります(ただし、新しい観測、新しい機能、など)これはどういう意味ですか? 新しい構造をサポートするには、データベーススキーマを更新する必要がありますか? データベースをリロードするには、すべてのイベントを再生する必要がありますか?
正直に言うと、私はそのような困難を避けたいと思います。
私のキャリアの中で、いくつかの単純な真実を理解するのに十分なプロジェクトを開発しました。 これらの真実の1つ-最も不変のもの-は変化です。 実際、アプリケーションとデータモデルが数か月後にどのように見えるかを調べる通常の方法はありません。 たぶん、すべてがゼロから3回書き直された後にのみ、それでも問題になります。
実際にこの未来になるまで、将来の推測を延期できるとしたらどうでしょうか。 すべてのイベントを記録するので、「世界の状態」をいつでも再構築して、古いイベントをすべて再生できますが、前述したように、これは非常に高価な喜びです。
しかし、ユーザーからのリクエストの直後に、必要な基準に該当するイベントを検索するためにリクエストを送信できるとしたらどうでしょうか? たとえば、ユーザーがいて、ユーザーがメールアドレスを持っているとします。 UserCreatedイベントとEmailChangedイベントを作成したとします。 すべてのユーザー(または1人でも)のすべてのイベントを再生する代わりに、UserCreated(id :)と最後のEmailChanged(userId :)を検索する場合はどうでしょうか。
うん ユーザーに関する必要な情報は、イベントを再生せずに、必要な場合にのみ要求できます!
// Pseudocode-ish User's email retrieval public class User { public String email() { return query(equal(EmailChanged.ID, id), descending(EmailChanged.TIMESTAMP)).first(). email(); }
ユーザーの電子メールを見つけるためのアルゴリズムがこれまでに変更された場合、ユーザー#email()メソッドを変更するだけです。 さらに、User#email()メソッド自体を記述するまで、これがプレゼンテーション用のデータを正確に構成する方法であることを知る必要はありません。 イベントのすべてのデータを、可能な限り何も失うことなく書き留めるだけです。
さらに興味深いことに、このアプローチは次の結論につながります。実際、「世界の状態」の普遍的なバージョンはありません。 私たち人間が私たちの周りの世界と現実を異なって知覚するように、文脈に応じて、プログラムは異なるプリズムを通して現実を知覚することができます。
このアプローチには何か問題がありますか? もちろん。 たとえば、検索クエリに時間がかかる場合。 ただし、このようなボトルネックが検出された場合、何らかの前処理またはキャッシングを通じて最適化できます。 コストのかかるリクエストを避けることはもちろん素晴らしいことですが、私たちは現実の世界に住んでいます。
これは、イベントの記録中に実行するイベントハンドラーが必要ないことを意味しますか? これは、特にサードパーティのコンポーネントによって実装されるドメインで、変更に対応するのに良い方法ではないと思います。 各イベントでこれを行う意味がわかりません。
ところで、ここで、このアプローチを使用することの別の興味深い結果があります。 APIとしてのGraphQLの人気の高まりにより、ますます多くのアプリケーションが、転送されるデータの量とクエリの数を最適化し、必要な最小値のみを要求および受信しています。 イベントからのデータの「怠collectionな」コレクションと一緒に、リクエストされていないデータの部分に「世界の状態」を構築することはありません。
上記のアプローチは、Domain Protocolと呼ばれる拡張機能を含むEventsourcingプロジェクトで使用されます。 プロジェクトにはGraphQL用のアダプターもあります。 このプロジェクトは完全にオープンであり、Mozilla Public License 2.0の下でライセンスされています。 最近、非営利組織のEventsourcing、Inc.が設立されました。 プロジェクトのさらなる開発とサポート。