見出し画像

SalesforceのPub/Sub API、プラットフォームイベントなどEventBusに関連する機能を整理してみた

こんにちは遠藤です。
ゆるっとSalesforce #38では、SalesforceのEvent BusとEvent Busにつながる機能やAPIを整理した内容を発表しました。

Salesforceプラットフォームでイベント駆動なシステムを実装するための仕組みには、変更データキャプチャ、プラットフォームイベントといった機能や、それらを操作するAPIもApexからPub/Sub APIやStreaming APIといくつかあります。

これらはすべてEvent Busを介してイベントをやりとりするわけですが、個々に見ていくとドキュメントも分かれているため全体像がつかみにくいものです。そこで、SalesforceのEvent Busを中心としてそれとつながる各機能やAPIがどう関係しているのか?全体像を整理することにしました。

今回は各機能およびAPIの詳細については解説をしません。しかし、全体像を把握することによって改めてそれぞれの詳細に踏み込む際の助けになるのではと思います。

Salesforce Event Busと関連する機能たち

Event Busは、プラットフォームイベントや変更データキャプチャイベントなどをSalesforce内外のシステム間で(ほぼ?)リアルタイムにデータをやりとするための基盤で、Salesforceの標準機能です。

以下の図は、Salesforceの技術ブログ記事、TrailheadやcodeLiveの動画などでも度々登場するものですが、解説のために改めて整理したものになります。
中央のEvent Busに対して上に配置されているものはイベントを公開(Publish)する側の機能とAPI郡です。下に配置されているものはイベントを購読(Subscribe)する機能とAPI群を表しています。

また、左側はプラットフォーム外部、右側はプラットフォーム内からイベントを公開・購読する機能やAPIとなっています。

※ 他に図に含まれていない機能としては、イベントリレーがありますが、今回は調べていません。

以下、それぞれを簡単に説明していきます。

Salesforceプラットフォーム内からイベントを公開する機能

図の右上のSalesforceプラットフォーム内からイベントを公開する機能には以下があります。

変更データキャプチャ

オブジェクトのレコードの作成、更新、削除、復元が実行された際にイベントを発行してくれる機能です。
設定の「変更データキャプチャ」でオブジェクトを選択するだけで有効化されます。

標準画面での操作、Apexやフロー、APIからのレコードの作成、更新、削除、復元処理について一律にイベントを発行してくれます。

プラットフォームイベント

オブジェクトの作成、更新、削除、復元以外のタイミングでイベントを発行したい場合に使用します。

Salesforceプラットフォーム上では、Apexやフローを使用してイベントを発行することができます。(未検証ですが、Lightningコンポーネントからもイベントレコードを作成することで発行することができるようです)

Spring '19以降、定義できるプラットフォームは大規模プラッフォームイベントにのみです。ドキュメントには大規模プラットフォームイベントという単語が度々登場しますが、現在は通常のプラットフォームイベントと置き換えて読見進めて問題なさそうです。

参考: 標準量プラットフォームイベントの廃止

Salesforceプラットフォーム内でイベントを購読する機能

図の右下のSalesforceプラットフォーム内でイベントを購読するには以下のような方法があります。

変更データキャプチャ

ApexトリガーおよびLightningコンポーネントのempAPIで購読できます。

フローのプラットフォームイベントトリガーフローでは変更データキャプチャイベントは購読できません。実際に選択できないか確認してみましたができませんでした。

変更データキャプチャをApexトリガーで処理する目的のひとつはトランザクションを分けたい場合があります。例としてはトリガーからコールアウトしたい場合にfutureアノテーションを使うことがありますが、変更データキャプチャのトリガーを使用するほうがきれいに実装することができます。

プラットフォームイベント

Apexトリガー、プラットフォームイベントトリガーフローおよびLightningコンポーネントのempAPIで購読できます。

Salesforceプラットフォーム外からイベントを公開する機能

図の左上のSalesforceプラットフォーム外のアプリケーションからイベントを公開する方法は以下のような方法があります。

プラットフォームイベント

REST APIやPub /Sub APIなどからイベントを発行できます。
REST APIとPub / Sub APIのどちらを使うか?ですが、大量のイベントを一度に公開するようなケースはPub / Sub APIの方がパフォーマンスが良いようです。(参考: Make the Most of Platform Events Through the Pub/Sub APIのBenchmarking

変更データキャプチャ

REST API、Bulk APIなどを利用して、オブジェクトのレコードを更新した場合は、Salesforceプラットフォーム側で「変更データキャプチャ」のイベントが発行されます。

Salesforceプラットフォーム外からイベントを購読する機能

図の左下のSalesforceプラットフォーム外のアプリケーションからイベントを購読するには、Streaming APIとPub / Sub APIが利用できます。

Streaming APIとPub / Sub APIのどちらを選択するかは、今後は理由がない限りは後継のPub / Sub APIを利用するのが良さそうです。

開発ガイド参考リンク:

Event BusにつながるAPIのプロトコルを確認

次にSalesforceプラットフォームと接続する各APIについてプロトコルも確認していきます。プロトコルを抑えておくことは、ライブラリの選定やシステム構成を考えるうえで必要となります。また、どの方式で通信しているか把握していることはトラブルシューティングの際にも役に立つかと思います。

以下は、主にSalesforceの外部とやり取りするAPIで使用されるプロトコルを示しています。Lightning UIについてはSalesforceのインスタンスとクライアントであるブラウザの間の通信プロトコルになります。

左上のREST、SOAP、BUlK APIは一般的なHTTP通信です。

左下、リアルタイム処理用の古いAPIであるStreaming APIは、CometDというプロトコルを使用しています。CometDはロングポーリングとも言われますがHTTP/1.1上でリアルタイムな処理を実装する仕組みです。

右下に移って、Lightning UIは、AuraやLightning Webコンポーネントでlightning/empApiを使用した場合を想定しています。LEXの標準機能でもempApiが内部で使用されていると思いますが、これらの通信方式もCometDとなっています。

Streaming APIの後継であるPub / Sub APIはgRPCのStreaming機能を使用して実装されています。こちらはHTTP/2をベースとしたプロトコルになっています。ポートも7443と80ではありません。外向けのポートが制限されているセグメントにアプリを配備する場合には、インフラ担当者にポートを開けてもらう必要がありそうです。

プラットフォームイベントの制限

プラットフォームイベントの公開と配信の制限について調べたことをまとめています。変更データキャプチャ イベントについては公開については特に制限はありませんが、配信の使用量はプラットフォームイベントと共有されます。

配信されるイベントのデフォルトの割り当てと使用量ベースのエンタイトルメントは、大規模プラットフォームイベントと変更データキャプチャイベント間で共有されます。

プラットフォームイベントの割り当て | プラットフォームイベント開発者ガイド

ところで、ドキュメントを読んでいて公開と配信はなんのことか?はじめはよく分からなかったのですが、公開(Publish)はEvent Busに向かってイベントを公開することで、配信(Delivery)はEvent Busから各クライアントに向かってイベントを送ることのようです。

最初の図の真ん中あたりに記載しています。

現在の利用状況は設定のプラットフォームイベントのページで確認できます。

詳細な統計情報については、PlatformEventUsageMetricオブジェクトに対してクエリーすることで取得できます。

公開/配信数としてカウントされる箇所ですが、以下のように異なっています。

  • 公開: Apex、Pub/Sub API とその他の API、フロー、プロセスビルダープロセスなど、すべての公開メソッド

  • 配信: CometD、 Pub/Sub API クライアント、empApi Lightning コンポーネント、イベントリレー

気をつける点としては、配信は公開されたイベント1つについて購読するクライアント(Event Consumer)の数が掛けられることです。
公開は、Apexやフローなどプラットフォーム内からのイベント公開もカウントされるので制限がゆるい理由らしいですが、購読するクライアントが多いと配信の方が制限がかなり厳しいように思います。

とくにLightningコンポーネントで利用する場合は、クライアントがユーザー数分になるため追加ライセンスを購入する必要がありそうです。また、変更データキャプチャはカウントされませんが、変更データキャプチャによって公開されたイベントの配信はカウントされるので、こちらも気をつける必要があります。

開発ガイド参考リンク:

リプレイ ストアについて

Event Busは、プラットフォームイベントおよび変更データキャプチャイベントを72時間保存してくれるデータストアを提供しており、クライアントが切断されていた間に受信し逃したイベントを取得することができます。

Salesforceはプラットフォームイベントおよび変更データキャプチャイベントを72時間保存します。Pub/Sub APIを使用すると、保存期間内のイベントを取得することができます。保存されたイベントの取得は、クライアントが切断された後、見逃したイベントをキャッチアップしたい場合に役立ちます。

Event Message Durability | Use Pub/Sub API

※ Streaming APIは若干対象イベントが異なるので開発ガイドを参照ください。

リプレイストアに保存されたイベントをどこから再生するかはいくつかのオプションがあります。

  • Earliest: 最も古いイベントから購読を開始するオプションで、重複イベントが発生する可能性があります。

  • Latest: 最新のイベントから購読を開始するオプションで、一部のイベントを見逃す可能性があります。

  • Custom (Replay ID): 特定のReplay IDから購読を再開するオプションで、イベントを見逃すことがなく、重複を最小限に抑えることができます。

しかし、基本的にはCustomが推奨されています。配信されたイベントのペイロードには「replay_id」が含まれているのでこれをアプリケーションで保持しておき、再接続時に前回保持したreplay_idを指定して再開するように実装します。
具体的な実装方法については、Pub / Sub API 開発ガイドのQuick Startに紹介されているリポジトリのコードで参照できます。

また、イベント中にコメントいただいた考慮事項ですが、イベントを公開した際にEvent Bus内部のストレージへの保存に失敗する場合があるそうです。これはドキュメントに記載がある通りでシステム構成上防げないのではないかと想像しています。

まれに、最初または後続の試行時にイベントメッセージが分散型システムに保持されない場合があります。つまり、イベントはサブスクライバーに配信されず、復旧できません。

プラットフォームイベントの定義および公開に関する考慮事項 | プラットフォームイベント開発者ガイド | Salesforce Developers

開発ガイド参考リンク:

ユースケース

イベントで紹介したデモは、「E-Bikesで発注があった際に工場(生産)の承認を得る」というものでしたが、このユースケースはそれほどリアルタイム性を必要としない気もするのであまりいい例ではなかったかもしれません。

Trailheadなどで紹介されているユースケースとしては以下のような物がありました

1. リアルタイムデータ同期

SalesforceとERPなど基幹システムとのデータ同期

例えば、Salesforceで取引先情報が更新された際に、即座にERPなどバックエンドのシステムに反映させたい場合、変更データキャプチャを使用してデータの変更をPub/Sub APIで受信しバックエンドのシステムに反映するなどが考えられそうです。

2. リードジェネレーションの自動化

ウェブサイトからのリード生成とSalesforceへの自動登録

ウェブサイトでフォームが送信されたときにプラットフォームイベントを発行し、Salesforceにリアルタイムでリード情報を登録します。このイベントをトリガーとして、即座にフォローアップの自動メール送信や営業担当への通知を行うこともできます。

3. イベント会場での行動データの収集

Dreamforce '24では、イベント会場からアプリにバッジを配信する仕組みもPub / Sub APIが使用されていたそうです。

Experienceクラウドと組み合わせればこういったシステムは簡単に実装できそうですね。


簡単に3つのユースケースを紹介しましたが、Salesforce Architectsの記事「Event-Driven Architecture」にはイベント駆動のシステムを利用した設計パターン例がいくつも紹介されていますが、各パターンのBusiness Use Case Exampleに具体的なユースケースが紹介されています。こちらも参考になりそうです。

デモ解説につづく

イベントの後半で紹介したデモはPub / Sub APIを中心としたものでしたので、解説はEvent Busの概要と別の記事にまとめました。
デモのコードの解説については以下の記事を参照ください。

おわりに

以上、Event Busと周辺に存在する機能とAPI郡について全体像を見てきました。

イベント中の議論で気がついたことでもありますが、イベント駆動なシステムのユースケースは、ユーザーエクスペリエンス上重要な場合にのみ検討するのが良さそうです。採用する場合も公開に失敗した場合のハンドリングを考慮して設計する必要があります。

まだ、きちんと読んでいないですが、こちらの記事も参考になりそうです。

今回のイベントで解説した内容はあくまで概要で、各機能詳細については私もまだ把握できていないところも多々あります。以下、今回参考にした開発ガイド、記事、動画へのリンクをまとめてありますので、もっと詳しく知りたいかたは各リンクを辿ってみてください。

参考情報

開発者ガイド

デモで紹介したソース

youtube Salesforce Developersチャンネル

Salesforce Architectsの記事

Event-Driven Architecture | Salesforce Architects

その他ブログ記事