「イベントソーシング」の「イベント」というワードチョイスは適切なのか?
この記事を書くに至った背景
株式会社ジェイテックジャパン CTOの高丘 @tomohisaです。昨日、イベントソーシングのイベントについて以下の記事を書きましたが、この記事はフォローアップ記事です。よろしければ元の記事もご覧ください。
2023/12/17追記:
ジェイテックジャパンで開発してきた、イベントソーシング・CQRSフレームワーク、「Sekiban」をリリースしました! www.sekiban.dev/jp/
こちらの記事にかとじゅんさんから適切なコメントをいただきました。
イベントは事実であって、世界は事実の総体であり、事物の総体ではない。とても上手くまとめてくださっています。私もイベントソーシングを使い始めて、オブジェクト指向で考えるより、イベント(事実)を中心にモデリングしていく方が複雑な事象をモデリングしやすいと感じています。さらに新しい事象、事実のパターンに気がついた時、プロパティを増やすというよりも、イベントの種別を増やす方がシステムに機能を追加しやすいと感じています。
この視点は実は前の記事でも紹介したYouTubeビデオにも取り上げられていました。
ここでGreg Youngの元ツイートに対して、Derek Comartin (このYouTubeの運営者)が提案をしています。「イベントソーシングという名称はFact Sourcing(ファクト(事実)ソーシング)」の方が良かったのではないかと言っています。以下のツイートですね。
こちらを見て、確かにイベントソーシングを調べ始めた時に、個人的にも少し理解するのに腑に落ちなかった点があったことを思い出しました。この記事では以下の点について扱います。
- イベントソーシングの「イベント」でどのように「事実」を記録するのか
- イベントソーシングの「イベント」よりも適切な言葉はあるのか
イベントソーシングの「イベント」でどのように「事実」を記録するのか
イベントソーシングの「イベント」には実は記述ルールがあります。基本的なものは以下のものです。
1. 実際に起こったことを「過去形」で記録する
イベントソーシングのイベントは、使って慣れてくると「事実」というのがしっくりきます。過去形で表現することで、システムとしては、すでに起こったこと、事実を報告するという意味合いがあります。「OrderSubmitted」、「PaymentReceived」や「ItemsShipped」という感じで、過去形のイベント名称とします。
ステートソーシングで作成する時には、事実をデータベースで管理するように作るのが自然な実装となります。イベントソーシングの場合、事実はビジネスの現場で起こり、その事実をシステムに記録するという意図で設計します。
Greg Youngがよく例に挙げる点として、倉庫からの出庫処理の話があります。
3つのアイテムを出庫したいケースがあるとします。
ステートソーシングで作成した時に時々バグや運用ミスで起きるケースとして、システム上の在庫数が0なので出庫できませんというエラーが出るようになってしまうことがあります。これは商品を削除し忘れたケースも考えられますし、入庫の数字を入れ忘れたのとも考えられます(もちろん在庫がなくても出庫可能にするシステムをステートソーシングで作ることは可能です)。
イベントソーシングで設計する場合出庫したという事実を記録することが主な関心事となります。計算上システムにいくつあるかにかわらず、担当者が3つのアイテムを倉庫で見つけて出庫処理をしたということは、その事実はビジネスの現場で発生しているため、受け入れることになります。出庫後に在庫数が0以下の計算になってしまった時にアラートを出して倉庫管理係に検品依頼を出すような通知を作成します。
2. イベントからステートを計算する際に、例外で中止しない
イベントソーシングにおいてある時点のステートを計算するためには、最初のイベントからイベントステートに起こす変化を計算して、その時点のステートを計算できます。この処理はプロジェクションとも呼ばれていて、イベントが起きるたびに再計算されます。そのため、イベントからステートを導き出す処理に関しては、例外を起こすことのないコードとすることが必要となります。
加えて、イベントはすでに発生した事実ですので、過去のイベントは後から変更したり取り消すことはできません。このことから、間違えた入力などがあったときは、修正や取り消しのイベントを新たに起こすことにより、よりイミュータブルに処理する必要があります。
上記の2つの特性を実現する「イベント」はすでに起きた事実となります。ただこの事実には色々な実装方法があります。
時間のかかる計算処理がある場合は、以下のようなイベントを作成可能です。
- 計算処理が終了した(計算結果をイベントとする)
- 計算するリクエストを送信した(計算を開始するリクエストをイベントとして記録する)
- 計算結果を確認した
このようにイベントを設計することで、1つの処理で計算処理を全て行うのではなく、まずリクエストだけを作成することにより、高速にイベントを作成してユーザーに返すことができます。リクエストが作成された後に、バックグラウンドや、別のマイクロサービスで時間のかかる計算処理を行うことも可能です。
イベントソーシングの「イベント」よりも適切な言葉はあるのか
イベントソーシングで使用する「イベント」は過去に起きた事実を記録すると意味があります。しかし最初この表現で意図を理解するのは難しかった記憶があります。そのときは「イベント」という言葉を聞いて、「定期的に起きるイベント」や「将来のために計画するイベント」も含めた「イベント」という言葉を想像してしまったためです。
今回の記事を書いていて少しその点が疑問になったので、ChatGPTに聞いてみました。英語で最初に質問したので、その後に和訳を入れています。
tomohisa
イベントソーシングでは、なぜイベントは過去文でなければならないのですか。一般に、「イベント」という言葉には過去・現在・未来の時制が含まれます。
ChatGPTの答え
イベントソーシングでは、イベントは、すでに行われた完了したアクションまたは発生を表すため、過去形のステートメントとして記録されます。イベントとは、すでに起こったことの記録であり、モデル化されたシステムの状態に永続的な影響を与えるものである。例えば、金融取引システムを考えてみよう。このシステムのイベントは、「2020-06-01に口座Xに100ドルが入金された」というものであろう。このイベントは、すでに起こった事実を表しており、変更したり元に戻したりすることはできない。このようにイベントを記録することで、イベントソーシングは、システムで起こった変化を監査可能な記録として提供し、イベントの履歴からシステムの現在の状態を再構築することを可能にする。
また、イベントに過去形の記述をすることで、イベントの不変性を確保し、イベントが既に行われたものであり、変更できないことを明確にすることができる。これは、システムの一貫性と信頼性を確保し、保存されるデータの完全性を維持するために重要である。
tomohisa
しかし、イベントソーシングの「イベント」という言葉は2つの異なる意味を持ちますが、イベントソーシングの「イベント」という言葉にはもっと良い言葉があるのでしょうか。
ChatGPTの答え
はい、一般的に使用される「イベント」という言葉は、イベントソーシングの文脈における「イベント」とは異なる意味を持つことがあるというのは正しいです。イベントソーシングでは、「イベント」という言葉は、モデル化されているシステムで起こった変化や変換を表す特定のタイプのレコードを指します。イベント」という言葉のより一般的な用法との混乱を避けるために、イベントソーシングの文脈で一般的に使用されるいくつかの代替用語には、「ドメインイベント」、「システムイベント」、「状態遷移」、または単に「遷移」などがあります。これらの用語は、イベントソーシングにおけるイベントが、システムで起こった特定の変化の記録であり、システムの現在の状態を定義する上で重要な役割を果たすという事実を強調するものである。
最終的には、用語の選択は慣習や個人の好みの問題であり、最も重要なことは、使用する用語が明確に定義され、システム全体で一貫して使用されることです。
www.DeepL.com/Translator(無料版)で翻訳しました。
以上がChatGPTとの会話です。さすがイベントソーシングについてもよく理解していますね。特に以下の表現が気に入りました。
イベントに過去形の記述をすることで、イベントの不変性を確保し、イベントが既に行われたものであり、変更できないことを明確にすることができる。これは、システムの一貫性と信頼性を確保し、保存されるデータの完全性を維持するために重要である。
上記の重要な点をよく理解していて、過去形にする理由まで説明してくれるのがなかなかやりますね。
「イベント」という名前に関しても代案をいくつか提案してくれています。YouTubeで提案されたものも含めて以下のようなものが提案されています。
- Fact (事実)
- ドメインイベント
- システムイベント
- 状態遷移
- 遷移
このように見て考えてみると、Fact Sourcingと言われてもいまいちピンとこない気がします。他のものも長くて理解しにくい気がします。長くいうと「ドメインイベント」は適切と感じますが、「ドメインイベントソーシング」は少し長いですね。こう考えてみると、ある程度最初に理解するステップさえ踏めば、「イベント」とシンプルに述べるのはわかりやすくて良いと感じました。
結論
今回の記事の結論を箇条書きにすると以下になります。
- イベントソーシングにおけるイベントは、実際に発生した事実を過去形で記録する
- イベントを処理してステートを出す時には、例外を発生させてはいけない
- イベントという言葉には現在、過去、将来を含む意味はあるが、イベントソーシングにおけるイベントは、過去に起きた事実を意味する
- 他にも代案があるが、理解してしまえば「イベント」という言葉が一番しっくりくる
イベントソーシングは最初の分かりにくさやとっつきにくさがありますが、一度理解して使用すれば、とても強力なモデリングツールとなります。ジェイテックでは、これらのコンセプトをC#とCosmos DBを使用して実装したイベントソーシングフレームワークをオープンソースで近々リリースしたいと準備しています。
Discussion