SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

IDDD本から理解するドメイン駆動設計

実践DDD本 第8章「ドメインイベント」~出来事を記録して活用~

IDDD本から理解するドメイン駆動設計 第8回

  • X ポスト
  • このエントリーをはてなブックマークに追加

イベントストアとは

 イベントストアとは、発生したイベントの履歴をストレージに記録する方法です。格納したイベント情報を利用者に公開することで活用します。利用側は必要に応じてイベント発生元のドメインモデルを取得して、自分の境界づけられたコンテキストに取り込みます。

イベントストアとRESTを用いた他システムへのイベント連携
イベントストアとRESTを用いた他システムへのイベント連携

 イベントストアには、次のようなメリットが備わっています。

  • メッセージ基盤を通してドメインイベントを発行するキューとして使用できる
  • モデルで発生したイベントを全て履歴として記録できる(調査や監査に利用)
  • イベントストアのデータを使って、分析や予測ができる(後から集計が可能)
  • イベントを用いてリポジトリの構築を行い、集約の再構築ができる(イベントソーシングにてデータパッチやデバッグも可能)

イベントストアの実装イメージ

 イベントストアの実装例としては、「イベントストア(EventStore)」インタフェースを利用してイベントの履歴情報をストレージへ格納します。イベントストアのストレージはMySQLのようなRDBや、LevelDBのようなNoSQLなどから最適な製品を選択します。どのストレージを選択するにしても、ドメインモデルの情報とイベント履歴の整合性が保たれるように注意します。

イベントストアの実装イメージ
イベントストアの実装イメージ

 ストレージには「ストアドイベント(StoredEvent)」クラスをシリアライズした内容が格納されます。これらは「ドメインイベント(DomainEvent)」インターフェースを実装するイベントクラスから変換することができます。

自立型のサービスのメリット

 他の境界づけられたコンテキストと連携する場合、ドメインイベントを用いると「自立型のサービス」になることがメリットとして挙げられます。自立型のサービスとは、他のサービスに依存せずに動作するシステムのことを指します。他のシステム(API/RPC)をリアルタイムに呼び出している場合、それらがダウンしていると、自身のサービスもダウンしたりパフォーマンスが低下したりする問題があります。

 そこで、自システムから外部システムを呼び出すのではなく、外部システムから自システム(イベント通知用REST API)を定期的にポーリングをしてもらうことでシステムの独立性を保つようにします。このような連携方式では、イベントを利用する外部システムが増えたとしても、イベント発行側にて変更しなくて良いメリットがあります。

RESTによる通知API

 イベント通知用のREST設計では、最新ログ(カレントログ)と過去ログ(アーカイブログ)の取得ができるように設計します。イベント数は膨大になるため、全レコードを取るのではなく、クライアント側で範囲を指定できるようにするのが一般的です。また、サーバーの負荷が高くならないようにキャッシュを使うようにします。

メッセージングミドルウェアによる連携方法

 上記ではRESTを用いたイベント通知について紹介しましたが、REST APIの実装をする代わりにメッセージングミドルウェアを使うことも可能です。メッセージングを行うミドルウェアにはActiveMQやRabbitMQ、Akka、NServiceBusといったソフトウェアが存在していますが、IDDDではRabbitMQを用いた例を紹介しています。

RabbitMQを用いたイベントの送受信

 RabbitMQはAMQP(Advanced Message Queuing Protocol)というメッセージングプロトコルに準拠した、オープンソースのミドルウェアです。AMQPとは、キューイングやルーティング(P2Pや出版購読モデル)、信頼性、セキュリティといった機能が定義されているプロトコルです。RabbitMQの場合、サーバーをインストールしクライアントAPIを介してアクセスするだけで、メッセージの登録や取得が可能です。RabbitMQを用いてイベントを送信する例は以下の通りです。

  1. イベントストアからイベントを一意な識別子でソートして取得する。
  2. 取得したリストを昇順にたどり、それぞれをエクスチェンジに送信する。
  3. メッセージの発行に成功したら、そのイベントがエクスチェンジに発行されたことを記録する。

 RabbitMQでは、エクスチェンジ(メッセージを送付する機能)にデータを連携するだけでデータを配信できます。配送方式や配送先の選択はRabbitMQ側で制御できます。

メッセージ基盤を使う時の注意点

 メッセージ基盤を使う時の注意点として、メッセージが重複処理される可能性を考慮しておく必要があります。例えば送信側でメッセージを送信した後で、ドメインモデル側のDBのコミットに失敗してしまうケースがあります。また、配送順番が保証されないことも考慮する必要があります。このような問題に対して、購読側にて複数回取り込んでも問題ないように実装します。通常、メッセージID(イベントID)を使用して、どこまでメッセージを処理したかを記録しておきます。

 最近は、AWSやAzureなどのクラウドサービスでもイベントの送受信機能やキューの機能が提供されています。サーバー管理の手間が不要で使い勝手も良いため、システム連携を行う場合の選択肢に入れてもいいでしょう。それぞれの、機能要件/性能/予算などのバランスから選択してください。

最後に

 以上、本稿ではドメインイベントについて、メリットやモデリング方法などを紹介し、シンプルな連携パターンから、イベントストアやメッセージ基盤を使ってイベントを連携していく方法を解説しました。次回はDDDの「モジュール」について紹介します。

参考資料

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
IDDD本から理解するドメイン駆動設計連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 青木 淳夫(アオキ アツオ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/10392 2017/09/13 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング