GoF以外のプログラミング・デザインパターン #19 Event Sourcing

2025/12/10

プログラミング 学習

t f B! P L
eyecatch Event Sourcing(イベントソーシング)は、「データの現在状態」ではなく「状態を作り出した出来事(イベント)の履歴」を保存するアーキテクチャパターンです。 通常のアプリでは「最新の状態」をDBに保存しますが、Event Sourcingでは「その状態に至るイベント(出来事)」を保存します。 要するに、最終値(最新状態)を1レコードで更新するのが通常のところ、複数発生するログを全て保持するようにするという履歴型データ保持形式です。 例)
[通常] - 残高 10000 [Event Sourcing]  - 入金 +5000  - 出金 -2000  - 入金 +7000

典型的な構成イメージ

Command └ Aggregate └ Event Store ↓ Projection (View DB) ↓ Query / API ・Command:ユーザー操作(例:入金コマンド) ・Aggregate:ビジネスロジック(ルールチェックや状態変更) ・Event Store:イベント(出来事)を保存 ・Projection:イベントを反映して「現在状態」を再構築

サンプルコード

class BankAccount { constructor() { this.events = [] } deposit(amount) { this.record({ type: 'Deposited', amount }) } withdraw(amount) { this.record({ type: 'Withdrawn', amount }) } record(event) { this.events.push({ ...event, date: new Date() }) } get balance() { return this.events.reduce((sum, e) => { return e.type === 'Deposited' ? sum + e.amount : sum - e.amount }, 0) } } const account = new BankAccount() account.deposit(5000) account.withdraw(2000) account.deposit(7000) console.log(account.balance) // 10000 console.log(account.events) // 履歴がすべて残っている

よく組み合わせられる技術

・CQRS(Command Query Responsibility Segregation) ・Kafka / RabbitMQ(イベントストリーム) ・EventStoreDB / DynamoDB Streams ・スナップショット機構(高速再構築用)

メリット

・すべての履歴が残る  いつ・誰が・何をしたのかを完全に再現できる。 ・監査・分析に強い  「なぜこの状態になったか」が後から追跡できる。 ・過去の状態を再構築できる  特定時点の状態を再生(replay)して検証できる。 ・CQRSと相性が良い  読み取り系と書き込み系を分けることで、高速なクエリと柔軟な集約が可能。

デメリット

・実装が複雑になる  イベントの再生・整合性管理・スナップショット処理が必要。 ・スキーマ変更が難しい  イベント構造を変更すると過去データへの影響が出る。 ・即座に「最終状態」を取得しにくい  すべてのイベントを適用しないと現在の状態がわからない。

あとがき

「Event Sourcing」は、“データの履歴”をファーストクラス市民にする設計思想です。 状態を保存するのではなく、“物語”を保存するような感じ。 どちらかというと、データベースへの保持ルール的なパターンです。 ただ、一時的な保持として、Webプログラミング特有のCookieやLocalStorageなどのキャッシュ保持にも使えるテクニックなので、 使いこなせると、安定したSPAなどの開発ができるというイメージが持てますね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ