イベントソースシステムの課題は、ソフトウェアが数々の変更を経ていても、何年も前にイベントストアに入れられたイベントを現在でも読むことができなければならない、ということだ、と、今年のDDD eXchangeカンファレンスでのプレゼンでGreg Young氏が述べている。プロジェクションやその他のシステムのような下流のコンシューマは古いイベントも新しいイベントも扱うことができなければならない。
システムを停止し、更新して元に戻すことができれば、イベントのバージョニングは比較的簡単だ。CQRSとイベントソーシングの権威であり、Event Storeのリードアーキテクトである氏にとって、真の課題はシステムを停止できず、同時に2つのバージョンのソフトウェアを実行している場合だ。
イベントをバージョニングする際の一般的なルールは、何かを追加してもバージョニングの競合が発生しないことだ。したがって、新しいバージョンのイベントの定義を破らない限り、新しいバージョンのイベントを追加することは問題ではない。また、同じイベントの古いバージョンから変換可能である必要がある。これが不可能な場合は、新しいイベントになる。これらのルールに従うと、古いバージョンがストアから読み取られると、処理される前にまずそれらを最新のバージョンに変換またはアップキャストできる。つまり、イベントハンドラは最新バージョンを処理する方法を知る必要があるだけだ。これは、新しいバージョンが多くの作成されている場合には重要な利点だ。新しいバージョンにプロパティが追加されたときに古いバージョンのイベントを変換できるようにするためには、データベースにnull不許可な列を追加する場合と同じ原則を適用する。つまり、デフォルト値を設定する。
型システムに基づくイベントでは、強力なスキーマを使用する。これで、シリアライザからのサポートは得られなくなる。シリアライざは、型またはスキーマと完全に一致するイベントのみを読み取れる。氏は、システムを停止してアップグレードできる場合にのみ、このアプローチが有効であると注意している。そうしないと、コンシューマは認識していない新しいバージョンのイベントを受け取り、デシリアライズできない、ということになる。それゆえ、氏は一般論としてはこの方法に反対だ。
イベントを記述するための形式としてJSONまたはXMLを使用する場合、弱いスキーマを使い、デシリアライズする代わりに、JSONのデータをイベントオブジェクトにマップする。JSONのデータとイベントオブジェクトに同じ名前のプロパティがあったら、値をイベントにコピーする。イベントに対応するJSONデータになかったら、対応する値はそのままにしておく。JSONの中にイベントのプロパティが見つからないなら、デフォルトの値を得る。これが機能するには2つのルールを追加する必要がある。何も名前変更してはならない。そして、プロパティの意味を変えない。この方法の利点の一つは新しいイベントのバージョンを作る必要がない点だ。最新のバージョンがあればいい。氏にとって、これは望ましい方法だ。というのは、ソフトウェアの古いバージョンが新しいイベントを読めるからだ。
弱いスキーマに関連するもう一つの選択肢として、ハイブリッドスキーマがある。これは、あるイベントに関連するオーダーの識別子を必須にし、その他を任意にすることでイベントが必要とすることに意味を持たせる。
その他の、より複雑な種類の問題には、公開すべきではないイベントや、集約された境界が間違っていることがわかった場合などがある。 既存のイベントを更新すると大きな問題を引き起こす可能性があり、氏はこれには強く主張している。代わりに、操作のためのストリームを使用することを好む。例えば、変換のストリームだ。リリースプロセスでは、1つのストリームから読み込み、変換を行ったり、新しいストリームに書き込んだりすることで、必要な変換を行うことができる。古いストリームは後で削除すればいい。ストリームを結合したり分割したりするという例もある。
イベントバージョニングについて、Young氏は現在、 長い期間に渡ってバージョンを処理することについて本を書いている。
来年のDDD eXchange Conferenceはロンドンで2018年4月26日、27日で開催される。
Rate this Article
- Editor Review
- Chief Editor Action