はじめに
第1回では、「Salesforceシステム連携のデザイン考察 1(ニーズとアプローチ)」と題して、連携のニーズとアプローチをお伝えしました。第2回では、最もニーズの多いと思われる「ビジネスロジック連携/データ連携」に焦点をあて、これまでの経験から外部システムと連携させるための検討ポイントや、Salesforceが備える機能を有効に活用し、具体的なアーキテクチャーをどう考えるかをお伝えしたいと思います。
※システム連携のアーキテクチャーに正解はありませんので、考え方の一例としてお読みください。
ビジネスロジック連携/データ連携の検討ポイント
Salesforceと外部システムを連携させる上では、Salesforceが備える機能を適切に選択し、さらに外部システムと連携させる上での条件や制約を考慮する必要があります。それらを調査・検討するうえでのポイント、および何故それらを検討するのか?といった理由を最初に説明します。
検討ポイントは大きく4つあります。
1. 連携対象
ソース/ターゲット
連携対象となるソースシステムとターゲットシステムを洗い出すと共に、システム間で交換する対象データを検討します。 この検討により、連携対象となるシステム数および概要レベルのインターフェース数を把握します。
プロトコル/API
連携を行う際に外部システムが要求するプロトコルを確認し、Salesforceと連携させる上で具体的にどのようなプロトコル変換を行う必要があるかを検討します。また、外部システムがAPIを保持しているかも確認します。
具体的には、HTTP/FTP/WebDAVなどの転送プロトコル、APIであればSOAP/RESTfulなどになります。さらに、セキュリティ要件を確認し、HTTPSやSFTP/FTPSによる通信の必要性も検討します。
データソース
連携を行う際に使用するデータソースを調査します。FTPでファイル転送されるデータはCSVファイル、固定長ファイル、XMLファイルなど具体的にどういった種類か、その文字コードが何であるかなどです。
RESTfulなAPIを使用するのであれば、リクエスト/レスポンスがXML、JSONといった形式の調査・検討が必要でしょう。データベースに直接接続するのであれば、接続するデータベースの種類はOracle、SQLServer、PostgreSQLといった具体的な種類を調査・確認します。
項目数/変換・加工数
連携を行う際に各インターフェースで交換されるデータに含まれる項目数を確認します。さらに、項目レベルのマッピングでターゲットシステムが受入可能な形式への加工・編集の必要性も確認します。
Salesforceと連携する場合、日付時刻の補正(GMT ⇔ JST)が必要になったり、Salesforce上のオブジェクト間の参照関係を作るためのIDへの変換箇所などは意識する必要があるでしょう。
提案や要件定義フェーズなどの早い段階で正確な項目数や変換・加工数を把握することは通常難しいと思いますが、個々のインターフェースの開発規模を算定する上でベースとなるため重要です。
連携対象を調査する大きな理由の一つは、「連携ミドルウェアの必要性」の検討になります。連携ミドルウェアは連携に特化しており、Javaや.netで開発を行うよりも高い生産性を発揮します。そのため、連携インターフェース数や連携項目数、変換・加工数が多い場合には、連携ミドルウェアの適用も検討します。さらに、連携ミドルウェアにはプロトコル変換するためのコンポーネントや、各種ファイル形式(CSV、XML、固定長など)の読み書き用コンポーネント、各種データベース製品用コンポーネント等が備わっていたり、後述する連携タイミングを柔軟に設定することができます。また、Salesforceとの連携を謳う製品には、Salesforceが標準提供する多くのAPIを容易に操作できるコンポーネントを持ち、Salesforce固有の制限事項をコンポーネント内でハンドリングできる製品もあります。
2. 連携タイプ
ロジック連携/データ連携
連携の要求がロジック連携なのか、データ連携なのかを検討します。この連携タイプの検討と後述の「3. 連携タイミング」により、Salesforceが備える機能、あるいはAPIの何れを使用した方がよいかの検討ポイントになります。
3. 連携タイミング
リアルタイム連携/バッチ連携
連携の要求が外部システムに対してリアルタイムに実施される必要があるのか、あるいは定期的なバッチ実行でよいのかを検討します。バッチで実行する場合には、1時間に1回、1日1回、週1回といったスケジューリングで連携するのか、またはFTP等でファイルが連携されたタイミングで実行するかなども検討します。
同期/非同期
リアルタイム連携を必要とした場合、その実行は同期されて実行される必要があるのか、あるいは非同期でもよいのかを検討します。
例えば、
1. 注文情報を入力保存し
2. 外部の決済サービスを呼び出し決済可否を確認
3. 決済可能であれば基幹システムから在庫を引き当てる
機能を考てみます。
1.の保存のタイミングに同期して、2. 外部の決済サービスを呼び出し、決済可能の判定に同期して、3. 基幹システムから在庫の引き当ての流れになります。一方、この2.の処理を単純に非同期で実装した場合には、決済可否の判定は別プロセスで実施されるため、決済可否の判定に関わらず、3.在庫引き当ての処理が行われることになります。
※上記一連の仕組みをVisualforceで作成していた場合に、決済サービスの応答に時間がかかるなどの理由で、決済サービスの呼び出しを非同期で実装し、応答をポーリングして待つなどのテクニックはあります。
連携タイプおよび連携タイミングを検討する理由は、「Salesforceが備える機能やAPIのどれを使用するか」の検討のベースになります。Salesforceは標準機能として外部システムと連携するための機能、Apexを使用した外部システムと連携するための機能、APIを使用した連携を行うことができます。連携でよく使われるAPIだけでも、SOAP API、REST API、Bulk APIがあり、これら機能のどれを選択して連携に使用するは重要で、そのため連携タイプ/連携タイミングの検討は欠かせません。
4. データ量・実行頻度
少量/大量
1回の連携で交換されるデータ量が少量なのか大量なのかをデータ連携するインターフェースごとに検討します。 常時/随時/定期
1回の連携で交換されるデータ量に加え、交換されるデータは1日の中で常時交換されるのか、ピークはあるのかといった情報から、インターフェース毎にある期間内(例えば24時間)に交換されるデータ量を予測します。
データ量、実行頻度を検討する理由は、「Salesforceの制限事項への抵触」の可能性を検討するためです。Salesforceでは外部システムと連携するための多くの機能が提供されていますが、それぞれに制限事項が設けられています。それら制限事項を理解し、データ量と実行頻度から制限に抵触する可能性を注意深く検討します。制限に抵触する可能性が出た場合には、本来最適と思われた連携方式以外の方式を採用するケースも起こりえるでしょう。
Salesforceと外部システムとのデータ連携を行う時、連携対象システム間で重複して保持するデータを双方向に連携する場合があります。例えば、社内の基幹システムが持つ取引先の更新をSalesforceに対して連携し、Salesforceでも取引先の更新を行った場合には、基幹システムに対して連携するケースです。この連携をバッチで行なっていた時、同一の取引先が双方のシステムで更新され、コンフリクトが発生するケースがあり、その扱いは課題となります。
このような課題を考えた時、双方のシステムで編集可能とする項目は本当に分離することができないのか?を最優先に検討します。例えば、基幹システムが持つ取引先の与信情報はSalesforceに連携を行うが、Salesforceでは参照のみが行えればよく、Salesforceで編集可能として基幹システムに戻す項目は、Salesforceでのみ編集可能とします。この場合、ユーザにとっての利便性を損なう可能性はありますが、業務的な観点とデータ整合性から、まずは分離可能であるかを検討した方がよいでしょう。(コンフリクトが頻繁に発生する可能性が予見されるなら、それは業務フローとして課題を抱えている可能性もあります。)
とはいえ、結果的に完全に分離できないケースもあります。この場合は、システム的な解消ルールと運用の決め事になると思います。ルールとしては、双方のシステムが持つレコードの最終更新日時をベースに、最も直近の更新を優先して上書きするなどです。この時、コンフリクトしたデータを別途ユーザに通知し確認できるようにする等の運用対処も併せて施すケースもあります。
Salesforce → 外部システム連携
Salesforceと外部システムの連携を考える時、Salesforceから外部システムにアクセスする、あるいは外部システムからSalesforceにアクセスするという、アクセス方向を意識することが重要です。
そして、そのアクセス方向と連携タイプ/連携タイミング、データ量/実行頻度の組み合わせにより、Salesforceが備える機能やAPIの何れを使用するのが最も適しているかが決まってきます。
最初に、Salesforceから外部システムへアクセスする方向の場合に、どの機能やAPIを使用するかを説明します。
ビジネスロジック連携 → リアルタイム → 同期
この連携パターンの場合、以下の方法がお勧めです。
Visualforce + Apex Controller + Apex SOAP or Apex HTTP
ユーザが操作を行うためのユーザインターフェースをVisualforceで実装し、そのビジネスロジックをApex Controllerでコントロールします。外部システムとの連携には、Apex Controllerから、Apex SOAP または Apex HTTPを使用したコールアウトを行います。
Visualforceページをユーザインターフェースとして紹介しましたが、Salesforce標準ページにカスタムボタンやカスタムリンクを設け、クリック時にVisualforceページを呼び出し、外部システムとリアルタイムに同期するケースでも同様な方式を適用可能です。
ビジネスロジック連携 → リアルタイム → 非同期
この連携パターンの場合、以下の3つが考えらそれぞれ特徴があります。
Outbound Message
Outbound Messageは、Salesforceの標準機能(マウスベースによるカスタマイズ)で設定できる機能で、Salesforceのワークフロールールのアクションとして実行されます。
ワークフロールールのアクションとして実行されるため、Salesforce上のオブジェクトの追加や変更を契機に、外部システムに対してSOAPメッセージの通知を行うことができます。
外部システムはSalesforceが指定するSOAPサービスを公開することになります。Outbound Messageですが、Salesforceの標準機能の組み合わせで実現できるメリット、およびSalesforce自身がSOAPメッセージを送信し、外部システムからの応答(ACK)を待ち、応答がない場合には自動的にリトライする仕組みを備えている点がメリットであり、特徴的です。
Apex Trigger + @future + Apex SOAP or Apex HTTP
Salesforceのデータ更新を契機にApexTriggerから、非同期実行メソッド(@futureアノテーションを付き)として、Apex SOAP または Apex HTTPを使用したコールアウトを行います。
非同期で外部システムと連携を行うため、連携の成功/失敗を適切に確認できる手段や、連携に失敗した場合のリカバリ方法などは十分に検討した方がよいでしょう。
また、Apexから@futureメソッドの呼び出しは10回まで、またライセンス毎に24時間あたりの非同期実行メソッドのコール可能な回数制限がある点も注意しましょう。
Streaming API
Streaming APIは、Salesforceのサーバで発生したデータ更新とその監視条件を契機に、クライントからの要求無しに情報を送信することができるAPIです。これまで、Salesforce上のデータ更新を外部アプリケーションからAPIを介してポーリングして検知していた場合、Streaming APIを使用することでAPIコール数を抑止して検知することが可能となります。
Streaming APIは「10分で分かる!使える!ストリーミング API」で分かりやすく説明されていますが、Salesforceからクライアント要求無しに情報を送信することができる一方で、送信された通知をクライアントが受信しない可能性がある点は考慮しなくてはなりません。
そのため、クライアントとなる外部システムでは、その受信を契機にクリティカルなビジネスロジック連携を実施することは十分慎重に検討し、さらに受信しなかった場合の運用や代替手段は考えておくべきでしょう。
データ連携 → バッチ → 非同期
この連携パターンの場合、以下の方法が考えられます。
Apex Batch(Database.AllowsCallouts)+ Apex SOAP or Apex HTTP
Salesforceには、Salesforceからバッチで大量データを外部システムに対して送信するAPIは提供されていません。そのため、大量データを処理するという観点からApex Batchを使用します。
具体的には、Database.Batchableインターフェースを実装したApex Batchのクラスに、さらにDatabase.AllowCalloutsインターフェースを実装することで、Apex Batchからコールアウトすることが可能になります。
この処理方式は非同期で外部システムと連携を行うため、連携の成功/失敗を適切に確認できる手段や、連携に失敗した場合のリカバリ方法などは十分に検討した方がよいでしょう。
また、大量データを処理することが想定されるため、ガバナ制限の抵触には注意が必要になります。
外部システム → Salesforce連携
外部システムからSalesforceへアクセスする方向の場合に、どの機能やAPIを使用するかを説明します。
ビジネスロジック連携 → トランザクション管理あり or 複雑なロジックあり → 少量データ
この連携パターンの場合、以下の方法がお勧めです。
Apex Web Service or Apex REST Service
Salesforceに対して外部システムから少量のデータ更新を行う場合に、Salesforce内部で複数のオブジェクトに対する更新を行う、あるいは複雑なロジックによるデータ検証を行うなどの要件がある場合、Apexを使用して、そのビジネスロジックを含むWeb ServiceまたはREST Serviceを開発して公開します。外部システムは公開されたサービスを呼び出します。
このタイプの適用に少量データの場合としているのは、Apexによる実装のため、ガバナ制限への抵触の可能性があるためです。
ビジネスロジック連携 → トランザクション管理あり or 複雑なロジックあり → 大量データ
この連携パターンでは、いくつかの注意点などがありオプションです。
Bulk API + Temporaty Table + Batch Apex
Salesforceに対して外部システムから大量のデータ更新の必要があり、そのデータからSalesforce内部で複数のオブジェクトに対する更新を行う、あるいは複雑なロジックによるデータ検証を行うなどの要件がある場合の方法です。
まず、大量のデータをSalesforceに書き込むという点は、大量データ処理用として提供されるBulk APIを使用してテンポラリなテーブルに格納します。次に、テンポラリなテーブルからデータを読み取り、複数オブジェクトに対する更新ロジックや、複雑な検証ロジックに関する実装を大量データ処理ができるようBatch Apexで実装します。
なお、Batch Apexでは、start、execute、finishの3つのメソッドを実装する必要があり、executeメソッドは複数回実行される場合があります。 (例えば、1000件のレコードを200件単位に分割した場合、5回executeメソッドが実行される)
ここで注意したいのは、処理レコード中にエラーがあった時にロールバックできるのは、executeメソッドの呼び出し単位であり、Batch Apexで処理した全レコードをロールバックすることはできないということです。
ビジネスロジック連携 → トランザクション管理なし and 複雑なロジックなし → 少量データ
この連携パターンの場合、以下の方法がお勧めです。
Bulk API or SOAP API or Rest API
Salesforceに対して外部システムから少量のデータ更新を行う場合で、トランザクション管理や複雑なロジックがない場合の方法です。
この場合、Salesforceが標準で提供するBulk API、SOAP API、Rest APIの何れかを使用するとよいでしょう。
なお、SOAP APIでは「AllOrNoneHeader」を使用することにより、APIコールで処理対象としたレコード中にエラーがあった場合に、そのAPIコールの範囲内でロールバックすることを許可できたり、1回のAPIコールで関連する複数のオブジェクトへの更新を行うことができる特徴があります。
ここで使用を検討するAPIは何れも24時間あたりのAPIコール数などの制限があります。そのため、連携を実施する上でのAPIコール数等の制限への抵触の可能性は十分調査・検討が必要です。
ビジネスロジック連携 → トランザクション管理なし and 複雑なロジックなし → 大量データ
この連携パターンの場合、以下の方法がお勧めです。
Bulk API
Salesforceに対して外部システムから大量のデータ更新を行う場合で、トランザクション管理や複雑なロジックがない場合の方法です。
この場合、大量データを処理するという点から最優先に検討するAPIはBulk APIになるでしょう。
なお、Bulk APIは24時間あたりのジョブ数制限(2000件)があります。そのため、連携を実施する上でジョブ数をどの程度消費するかは事前に確認する必要があります。
データ連携 → マスタデータがSalesforce
この連携パターンの場合、以下の方法がお勧めです。
SOAP API(query/queryAll、getUpdated、getDeleted)
Salesforceで更新されたデータを定期的に外部システムにレプリケーションするケースになります。
Salesforceには定期的に更新されたデータを外部システムに通知するAPIは提供されていないため、外部システムを起点にSalesforceに対し更新されたデータを取得することになります。
この場合、SOAP APIのquery/queryAllサービス、あるいはgetUpdated/getDeletedサービスを使用して差分データを取得する方法になります。
SOAP APIの各サービスの違いについては「SalesforceのAPIを知って連携ツールを使いこなそう 【第1回】」が参考になります。
データ連携 → マスタデータが外部システム
この連携パターンの場合、以下の方法がお勧めです。
Bulk API
外部システムで更新が発生したデータを外部システムに取り込むケースになります。外部システムで更新されたデータを定期的にSalesforceにレプリケーションするケースになります。 この場合、大量データを処理するという点から最優先に検討するAPIはBulk APIになるでしょう。
おわりに
第2回では、Salesforceと外部システムを連携させる場合の検討ポイントをこれまでの経験からお伝えしました。Salesforceとそれを取り巻く周辺システムとの連携を検討される上で、参考になれば幸いです。
最終回となる第3回では、今回お伝えした検討ポイントと適用するアーキテクチャーを考える実践として、仮想シナリオから具体的なデザインをお伝えしたいと思います。
なお、本ブログ執筆中に本家から「Salesforceと他のシステムを接続する際のパターン & ベストプラクティス」というドキュメントが公開されました。Salesforceと外部システムの連携アーキテクチャーを考える方は必読ですね!