背景と応用シナリオ
Salesforce アーキテクトの視点から: 現代のエンタープライズアーキテクチャにおいて、データは組織の生命線です。しかし、そのデータは多くの場合、ERP、基幹システム、カスタムデータベース、他のクラウドサービスなど、複数のサイロに分散しています。Salesforceを顧客関係管理(CRM)の中心として活用する上で、これらの外部システムに存在するデータをいかにして統合し、顧客の360度ビューを実現するかは、すべてのアーキテクトが直面する重要な課題です。
従来、この課題へのアプローチは主にETL (Extract, Transform, Load) プロセスに依存していました。つまり、外部データを定期的に抽出し、Salesforceのオブジェクトモデルに合わせて変換し、Salesforce内にコピー(ロード)する方法です。このアプローチは有効な場面もありますが、以下のようなアーキテクチャ上のトレードオフを伴います。
- データの陳腐化: バッチ処理の頻度によっては、Salesforce内のデータが最新でない可能性があります。
- ストレージコストの増大: 同じデータを二重に保持するため、Salesforceのデータストレージを消費します。
- 開発・保守の複雑化: ETLジョブの構築、監視、そしてデータモデルの変更に伴うメンテナンスは、相応の工数を必要とします。
- コンプライアンス上の懸念: 機密性の高いデータや、特定の地域に保持することが法的に義務付けられているデータをSalesforceにコピーできない場合があります。
ここで登場するのが Salesforce Connect です。Salesforce Connectは、ETLとは全く異なるアプローチ、すなわち data virtualization (データ仮想化) を提供します。これは、データをSalesforce内にコピーするのではなく、外部システムに存在するデータを「その場で」リアルタイムに参照、検索、そして(設定によっては)更新する機能です。データはSalesforceのUI上ではあたかも標準オブジェクトやカスタムオブジェクトのように見えますが、その実体は外部システムに存在し続けます。
具体的な応用シナリオ
- 受注管理: SAPやOracleなどのERPシステムに保存されている顧客の注文履歴や請求書情報を、Salesforceの取引先レコードの詳細ページにリアルタイムで表示する。営業担当はSalesforceを離れることなく、最新の取引状況を把握できます。
- 在庫確認: 外部の在庫管理システムと連携し、商談や商品ページでリアルタイムの在庫数を表示する。これにより、正確な納期回答や在庫引当が可能になります。
- レガシーシステムのデータ活用: オンプレミスに存在する古い基幹システムのデータを、APIを通じてSalesforce上に表示し、最新のモバイルアプリケーションやLightning Web Componentsから活用する。
- マルチ組織でのデータ集約: 複数のSalesforce組織を持つ大企業が、ある組織から別の組織のデータを参照する(例:グローバル本社組織から各地域の営業組織のデータを参照する)。
アーキテクトとして、Salesforce Connectは、データ統合戦略における強力な選択肢です。システムの疎結合性を保ちながら、ユーザーにシームレスなデータ体験を提供し、ストレージコストや開発の複雑性を低減できる可能性があります。
原理説明
Salesforce Connectの魔法の裏側には、外部オブジェクト (External Objects) と呼ばれる特殊なオブジェクトと、外部データソースに接続するためのアダプタが存在します。アーキテクチャを理解する上で、これらの構成要素を把握することが不可欠です。
1. 外部データソース (External Data Source)
まず、Salesforceがどの外部システムと通信するかを定義するのが「外部データソース」です。ここで接続先のURL、認証情報、そして使用するアダプタの種類を設定します。認証には、セキュリティのベストプラクティスである指定ログイン情報 (Named Credential) を使用することが強く推奨されます。これにより、認証情報(APIキーやパスワードなど)がコードや設定から分離され、安全に管理できます。
2. 接続アダプタ
Salesforce Connectは、主に3種類のアダプタを提供しており、接続先のシステムに応じて最適なものを選択します。
- OData 2.0 / 4.0 アダプタ: OData (Open Data Protocol) は、REST APIを介してデータを照会および操作するためのISO/IEC承認の標準規格です。多くのモダンなERPやSaaSアプリケーションがODataをサポートしており、標準的な方法で接続できるため、最も一般的に使用されるアダプタです。Salesforceは外部システムのODataエンドポイントにHTTPリクエストを送信し、返されたデータを解釈して外部オブジェクトにマッピングします。
- 組織横断アダプタ (Cross-Org): 他のSalesforce組織のデータにアクセスするための専用アダプタです。Salesforce APIを利用して、あたかも自組織のオブジェクトであるかのように、他組織のオブジェクトを操作できます。
- Apex Connector Framework: ODataをサポートしていない独自のREST/SOAP APIを持つシステムや、複雑なデータ変換ロジックが必要な場合に利用します。このフレームワークを使うと、Apexコードを記述して、Salesforceからのリクエスト(SOQLクエリなど)を外部システムのAPIコールに変換し、結果をSalesforceが理解できる形式で返すカスタムアダプタを開発できます。これにより、接続できるシステムの範囲が劇的に広がります。
3. 外部オブジェクト (External Objects)
外部データソースを設定した後、「検証して同期 (Validate and Sync)」機能を使用すると、Salesforceは外部システムのデータ構造(ODataで言えばエンティティ)を読み取り、対応する外部オブジェクトを自動的に作成します。外部オブジェクトは、カスタムオブジェクトと非常によく似ており、カスタム項目、ページレイアウト、リレーションなどを定義できます。
ユーザーが外部オブジェクトのレコードを表示しようとすると、以下のプロセスがリアルタイムで実行されます。
- ユーザーがレコードリストビューを表示、または特定のレコード詳細ページを開く。
- Salesforce Platformが、このリクエストが外部オブジェクトに対するものであることを認識する。
- Salesforce Connectが、関連付けられた外部データソースとアダプタを使用して、外部システムへのAPIコール(例: ODataのGETリクエスト)を動的に生成する。
- 外部システムがリクエストを処理し、データを返す(通常はJSONまたはXML形式)。
- Salesforce Connectが受け取ったデータを解析し、Salesforce UI上にレコードとしてレンダリングする。
この一連の流れがすべてオンデマンドで実行されるため、データは常に最新であり、Salesforce内にコピーが保持されることはありません。これがデータ仮想化の核心です。
サンプルコード
最も柔軟性の高い Apex Connector Framework を使用する場合、アーキテクトは開発チームと協力してカスタムコネクタを実装する必要があります。これは DataSource.Connection
クラスと DataSource.Provider
クラスを実装することで実現します。以下は、developer.salesforce.com に記載されている、クエリ処理部分を簡略化した公式のコード例です。
この例では、外部オブジェクトに対するSOQLクエリを受け取り、それを外部システムへのHTTPコールに変換し、結果を返す query
メソッドを実装しています。
// DataSource.Connectionクラスを継承したカスタムコネクタの実装 public class SimpleConnector extends DataSource.Connection { // 外部データソースの定義 private DataSource.ConnectionParams connectionInfo; // コンストラクタ public SimpleConnector(DataSource.ConnectionParams connectionInfo) { this.connectionInfo = connectionInfo; } // クエリが実行されたときに呼び出されるメソッド // SOQLはSalesforceによって解析され、QueryContextオブジェクトとして渡される override public DataSource.TableResult query(DataSource.QueryContext context) { // テーブル名の取得(=外部オブジェクト名) System.debug('Querying table: ' + context.tableSelection.table); // 外部システムへのHTTPリクエストを準備 Http http = new Http(); HttpRequest req = new HttpRequest(); // エンドポイントは指定ログイン情報から取得するのがベストプラクティス // ここでは例としてハードコード req.setEndpoint('https://api.example.com/data/' + context.tableSelection.table); req.setMethod('GET'); // 認証情報をヘッダーに設定 req.setHeader('Authorization', 'Bearer ' + this.connectionInfo.oauthToken); // HTTPリクエストを送信し、レスポンスを取得 HttpResponse res = http.send(req); // レスポンスボディ(JSON)を解析 List<Map<String, Object>> results = (List<Map<String, Object>>) JSON.deserializeUntyped(res.getBody()); // 結果を格納するための行リストを初期化 List<DataSource.Row> rows = new List<DataSource.Row>(); // 取得した各レコードをDataSource.Rowオブジェクトに変換 for (Map<String, Object> result : results) { // 新しい行を作成。テーブル名はcontextから取得 DataSource.Row row = DataSource.Row.create(context.tableSelection.table); // 各列(項目)に値を設定 for (String columnName : result.keySet()) { row.addCell(columnName, result.get(columnName)); } rows.add(row); } // Salesforceが理解できる形式 (DataSource.TableResult) で結果を返す // DataSource.TableResult.createで、クエリコンテキストと行のリストを渡す return DataSource.TableResult.create(context, rows); } // sync, upsert, deleteなどの他のメソッドも必要に応じてオーバーライドする // ... }
コードの注釈
DataSource.Connection
: すべてのカスタムコネクタが継承する必要がある基本クラスです。query
、sync
、upsert
、delete
といったメソッドをオーバーライドして、外部システムとの通信ロジックを実装します。query(DataSource.QueryContext context)
: 外部オブジェクトに対してSOQLクエリが実行されるたびに呼び出されます。context
オブジェクトには、対象テーブル(外部オブジェクト名)、選択された列(項目)、フィルタ条件(WHERE句)、順序(ORDER BY句)などの情報が含まれており、これらを元に外部APIへのリクエストを構築します。DataSource.TableResult.create(context, rows)
: 外部システムから取得したデータをDataSource.Row
のリストに変換し、最終的にTableResult
として返却します。Salesforceはこのオブジェクトを解釈して、クエリの結果としてユーザーに表示します。
注意事項
Salesforce Connectは強力なツールですが、銀の弾丸ではありません。アーキテクトは、その制約とパフォーマンスへの影響を深く理解した上で、適用を判断する必要があります。
パフォーマンスとガバナ制限
- レイテンシ: すべてのデータアクセスはリアルタイムのHTTPコールアウトを伴います。外部システムの応答速度が、Salesforceのページ表示速度に直接影響します。応答が遅いシステムとの連携は、ユーザーエクスペリエンスを著しく低下させる可能性があります。
- コールアウト制限: Salesforce Connectによるアクセスは、SalesforceのAPIコールアウト制限(例:1トランザクションあたりのコールアウト数、24時間あたりの合計コールアウト数など)の対象となります。特に、多くのユーザーが頻繁にアクセスする外部オブジェクトや、リストビューでの一括表示は、制限を消費しやすいため注意が必要です。
データモデルとクエリの制約
- リレーションシップ: 外部オブジェクトは、参照関係の親になることはできますが、主従関係の従側になることはできません。また、外部オブジェクト同士や、外部オブジェクトと標準/カスタムオブジェクトを繋ぐための「外部参照関係」や「間接参照関係」といった特殊なリレーションを使用します。
- SOQL/SOSLのサポート: 外部オブジェクトに対するSOQLでは、集計関数(
COUNT()
,SUM()
など)やGROUP BY
、HAVING
句などがサポートされていません。このため、Salesforceの標準レポートやダッシュボードで複雑な集計を行うことには向いていません。SOSLによる検索も限定的です。 - 書き込み操作: 外部オブジェクトに対する書き込み(作成、更新、削除)を有効にできますが、これもコールアウトを発生させます。大量のデータを一括で更新するようなバッチ処理には適していません。トランザクションの整合性を保証する仕組みも、外部システムの設計に大きく依存します。
セキュリティ
- 認証: 外部データソースの認証設定は、セキュリティアーキテクチャの要です。必ず指定ログイン情報を使用し、最小権限の原則に従って、外部システムへのアクセス権を持つ専用のサービスアカウントを設定してください。
- データ露出: Salesforce Connectを介して外部データを表示するということは、Salesforceのユーザーにそのデータへのアクセスを許可することを意味します。Salesforceのプロファイルや権限セットと、外部システムのアクセス制御を整合させる設計が必要です。
まとめとベストプラクティス
Salesforce Connectは、データ統合のツールボックスに加えるべき、非常に価値のある選択肢です。特に「データをコピーしない」という特性は、リアルタイム性、ストレージ効率、コンプライアンスの観点から大きな利点をもたらします。
アーキテクトとしての判断基準は以下の通りです。
- Salesforce Connectを選択すべき時:
- データのリアルタイム性が最重要である場合。
- 外部データの量が非常に多く、Salesforceにコピーすることが現実的でない場合。
- データガバナンスや法規制により、データをSalesforce内に保持できない場合。
- 必要な操作が主にデータの参照であり、複雑な集計やレポートを必要としない場合。
- ETL/インテグレーションツールを選択すべき時:
- Salesforce内で複雑なレポートや分析を実行する必要がある場合。
- 外部システムとの連携に、複雑なデータ変換ロジックが必要な場合。
- オフラインアクセスや、Salesforceのネイティブなパフォーマンスが求められる場合。
- 大量のデータを一括で書き込む必要がある場合。
アーキテクトとしてのベストプラクティス
- 適切なアダプタを選択する: 接続先がODataをサポートしているなら、まずはODataアダプタを検討します。カスタム開発の複雑性を避けられます。Apex Connector Frameworkは、最後の手段として、しかし強力な選択肢として残しておきます。
- 外部APIを最適化する: Salesforce Connectのパフォーマンスは外部APIに依存します。外部システムの開発チームと協力し、APIがサーバサイドでのフィルタリング(
$filter
)やページネーション($top
,$skip
)を効率的にサポートするように設計します。 - 入念なパフォーマンステストを実施する: 本番稼働前に、想定される負荷状況下でパフォーマンステストを行い、レイテンシやコールアウト消費量を測定し、ボトルネックを特定します。
- ユーザーエクスペリエンスを考慮する: 外部オブジェクトのリストビューやページレイアウトを設計する際は、一度に表示する項目数を最小限にし、関連リストの読み込みを制御するなどして、体感速度を向上させる工夫をします。
- 制約を関係者に周知する: Salesforce Connectの機能的な制約(特にレポートと検索)を、ビジネスユーザーやステークホルダーに事前に明確に伝え、期待値を正しく設定します。
Salesforce Connectを正しく理解し、アーキテクチャに組み込むことで、より俊敏でスケーラブル、かつ安全な統合ソリューションを構築することが可能になります。
コメント
コメントを投稿