Salesforce External Services の理解:宣言的インテグレーションでクラウドを繋ぐ

概要とビジネスシーン

Salesforce External Services は、OpenAPI (Swagger) 仕様を介して外部の RESTful API を Salesforce プラットフォームにシームレスに統合し、コード記述なし、または最小限のコードで利用可能にする強力なフレームワークです。これにより、開発者は複雑なインテグレーションコードを作成することなく、外部サービスの機能を Salesforce フロー、Apex、そしてさまざまな自動化ツールから直接呼び出すことが可能になり、開発効率と保守性を大幅に向上させます。

実際のビジネスシーン

シーンA - Eコマース業界

  • ビジネス課題:顧客がECサイトからSalesforce Commerce Cloudを通じて購入した注文に対して、外部の第三者決済サービス(Stripe, PayPalなど)での決済状況をリアルタイムにSalesforce Sales Cloud/Service Cloudで把握し、顧客サービスを向上させる必要がありました。従来の直接API連携は開発コストが高く、決済サービス側のAPI変更に対応する際のメンテナンスが負担でした。
  • ソリューション:External Services を利用し、外部決済サービスの OpenAPI 仕様を Salesforce に登録。これにより、決済状況確認、返金処理などのアクションが Salesforce フローから宣言的に実行可能になりました。決済状況の更新は、フローと連携したレコードトリガーフローで自動化されました。
  • 定量的効果:決済連携の開発期間を約50%短縮し、API変更への対応コストを20%削減。顧客サポート担当者はリアルタイムの決済状況をSalesforce画面上で確認できるようになり、顧客満足度が10%向上しました。

シーンB - 物流業界

  • ビジネス課題:複数の配送業者を利用しており、それぞれの配送追跡サービスAPIが異なるため、顧客サポート担当者が追跡情報を提供するために複数の外部システムにログインする必要がありました。これにより、顧客対応時間が長くなり、顧客からの問い合わせ解決までの時間が伸びていました。
  • ソリューション:各配送業者の配送追跡APIの OpenAPI 仕様を External Services に登録。登録されたサービスアクションは Salesforce フローで利用可能となり、取引先責任者や商談レコードから直接、現在の配送状況を照会・表示するカスタムコンポーネントが作成されました。
  • 定量的効果:顧客サポート担当者の平均対応時間が25%短縮され、顧客からの配送状況に関する問い合わせ解決率が向上。その結果、顧客満足度が15%向上し、サポート問い合わせ数が10%削減されました。

シーンC - 金融業界

  • ビジネス課題:住宅ローン審査において、外部の信用情報機関のAPIを呼び出して顧客の信用情報を取得する必要がありました。このプロセスは手動で行われるか、複雑な Apex コードによって実装されており、開発と保守にコストがかかっていました。
  • ソリューション:信用情報機関が提供する OpenAPI 仕様を External Services に登録。ローン申請フローにおいて、顧客の同意を得た上で、External Services のアクションを呼び出して信用情報を自動的に取得し、審査プロセスに組み込みました。これにより、信用情報取得から審査結果通知までの一連のプロセスが自動化されました。
  • 定量的効果:ローン審査プロセスを約30%短縮し、手作業によるオペレーションミスを削減。開発チームはインテグレーションロジックに費やす時間を削減し、よりビジネス価値の高い機能開発に注力できるようになりました。

技術原理とアーキテクチャ

External Services の基礎的な動作メカニズムは、OpenAPI (Swagger) 仕様を利用して外部の RESTful API を Salesforce が理解できる形式に「登録」することにあります。この登録プロセスにより、外部 API のエンドポイント、メソッド (GET, POSTなど)、リクエスト/レスポンスのデータ型が Salesforce のカスタムオブジェクトやアクションとして抽象化され、Flow Builder や Apex から呼び出し可能なコンポーネントが自動的に生成されます。

主要コンポーネントと依存関係

  • OpenAPI (Swagger) 仕様:外部サービスが公開している API のスキーマ定義です。JSONまたはYAML形式で提供され、エンドポイント、操作、パラメータ、データモデルなどを記述します。Salesforce はこの仕様を解析してサービスを登録します。
  • External Service 定義:Salesforce 内で OpenAPI 仕様をアップロードし、外部サービスを登録するエンティティです。登録後、そのサービスに含まれる各操作 (アクション) は Salesforce のオートメーションツールで利用可能になります。
  • Named Credential(名前付き資格情報):外部サービスへの認証情報を安全に保存・管理するための機能です。エンドポイント URL と認証プロトコル(OAuth 2.0、JWT、AWS Signature Version 4など)を定義し、認証情報は Salesforce によって自動的に処理されるため、Apex コード内にハードコードする必要がなくなります。
  • Credential:Named Credential の具体的な認証情報を保持するレコードです。ユーザーごとに異なる資格情報を使用できます。
  • Flow Builder:登録された External Service のアクションは、フロー要素(サブフロー、アクション)として利用でき、ノーコード/ローコードで外部サービスとの連携を含むビジネスプロセスを自動化できます。
  • Apex:開発者は、登録された External Service のアクションを Apex クラスから直接呼び出すことも可能です。これにより、より複雑なビジネスロジックや高度なエラー処理を実装できます。

データフロー

ステップ 説明 Salesforce コンポーネント
1. 定義 外部サービスの OpenAPI 仕様と Named Credential を Salesforce に登録します。 External Service 定義、Named Credential
2. 呼び出し要求 ユーザーアクション、レコード更新、スケジュールなどにより、外部サービスアクションの実行がトリガーされます。 Flow Builder, Apex, Process Builder
3. 認証・ルーティング Salesforce は Named Credential を使用して、安全に外部サービスへのコールアウトを認証し、ルーティングします。 Named Credential, Salesforce プラットフォーム
4. 外部API呼び出し Salesforce は、OpenAPI 仕様に基づいて生成されたリクエストを外部サービスのエンドポイントに送信します。 外部 RESTful API
5. レスポンス受信 外部サービスは処理結果を Salesforce に返します。 外部 RESTful API
6. 結果処理 Salesforce は受信したレスポンスを解析し、フローや Apex で利用可能な形式に変換します。 External Service 定義、Flow Builder, Apex

ソリューション比較と選定

外部システム連携には複数のアプローチがありますが、External Services は特定のユースケースで特に強みを発揮します。

ソリューション 適用シーン パフォーマンス Governor Limits 複雑度
External Services OpenAPI仕様を持つRESTful APIとの宣言的統合、Flow/Apexからのコード最小化での利用、迅速なプロトタイピング。 中〜高(外部APIの応答速度に依存) Apexコールアウト制限(1トランザクションあたり100回)、Named Credentialの非同期呼び出し制限(1日あたり250,000回) 低〜中(OpenAPI仕様の準備・調整が必要)
Apex Callouts カスタム認証やヘッダ/ボディの細かな制御が必要な場合、SOAP APIなど複雑なプロトコル、高度なエラー処理ロジックの実装。 高(カスタム実装により最適化可能) Apex CPU time, Heap size, DMLs, 1トランザクションあたり100回コールアウト、120秒の合計タイムアウト 高(全コード手書き、認証情報の管理)
Salesforce Connect (External Objects) 外部データをSalesforceオブジェクトとしてリアルタイムに表示・レポートしたい場合、外部データのCRUD操作をSalesforceから行いたい場合。 中(外部システムへの都度アクセスが発生) コールアウト制限あり、レコード数によるパフォーマンスボトルネックの可能性 中〜高(設定、外部システムへのアダプタ(OData, Apex Connector Frameworkなど)の知識が必要)

external services を使用すべき場合

  • ✅ 連携したい外部サービスが OpenAPI (Swagger) 仕様を提供しており、それが利用可能である。
  • ✅ ローコード/ノーコード(Flow Builder)での外部サービス連携を優先し、迅速なビジネスプロセスの自動化が必要である。
  • ✅ 開発リソースを節約し、インテグレーションコードの保守コストを削減したい。
  • ✅ 外部APIの認証に Named Credential を使用できる(OAuth 2.0、JWTなど標準的なプロトコル)。

不適用シーン

  • ❌ OpenAPI 仕様が存在しない、または複雑すぎて自動生成が困難な非標準 API との連携。
  • ❌ SOAP API のような RESTful 以外のプロトコルを必要とする場合。
  • ❌ 非常に高いパフォーマンスが要求され、ミリ秒単位でのレスポンスタイム最適化が必要な場合(この場合、Apex Callouts がより柔軟性を提供します)。

実装例

ここでは、External Services を利用して、外部のペットストア API (OpenAPI 仕様の一般的な例) を呼び出す Apex コードの例を示します。

ステップ1: OpenAPI 仕様の準備

まず、以下のような OpenAPI 2.0 (Swagger 2.0) 仕様(例として一部抜粋)があると仮定します。これを JSON または YAML ファイルとして保存します。

{
  "swagger": "2.0",
  "info": {
    "version": "1.0.0",
    "title": "Petstore API"
  },
  "host": "petstore.swagger.io",
  "basePath": "/v2",
  "schemes": [
    "https"
  ],
  "paths": {
    "/pet/findByStatus": {
      "get": {
        "summary": "Finds Pets by status",
        "operationId": "listPets",
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Status values that need to be considered for filter",
            "required": true,
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "available",
                "pending",
                "sold"
              ]
            },
            "collectionFormat": "multi"
          }
        ],
        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Pet"
              }
            }
          },
          "400": {
            "description": "Invalid status value"
          }
        }
      }
    }
  },
  "definitions": {
    "Pet": {
      "type": "object",
      "properties": {
        "id": {
          "type": "integer",
          "format": "int64"
        },
        "name": {
          "type": "string",
          "example": "doggie"
        },
        "status": {
          "type": "string",
          "description": "pet status in the store",
          "enum": [
            "available",
            "pending",
            "sold"
          ]
        }
      }
    }
  }
}

ステップ2: Named Credential の作成

設定 (Setup) から「名前付き資格情報 (Named Credentials)」を検索し、新規作成します。エンドポイント URL を https://petstore.swagger.io/v2 とし、認証設定(例:匿名)を行います。ここでは Petstore_NC という名前にしたと仮定します。

ステップ3: External Service の登録

設定 (Setup) から「外部サービス (External Services)」を検索し、新規登録します。ステップ1で準備した OpenAPI 仕様ファイルをアップロードし、ステップ2で作成した Named Credential を選択します。サービス名として PetstoreService などと指定すると、Salesforce は OpenAPI 仕様を解析し、listPets のような操作を自動的に作成します。

ステップ4: Apex からの呼び出し

External Service が登録されると、そのサービス内の各操作に対応する Apex クラスとメソッドが自動生成されます。以下の Apex コードは、登録された PetstoreServicelistPets アクションを呼び出す例です。

public class PetstoreIntegrationService {

    /**
     * @description ペットストアから指定されたステータスのペットリストを取得する
     * @param status 検索対象のペットのステータス (例: 'available', 'pending', 'sold')
     * @return 取得したペットのリスト。エラーの場合は空のリストを返す
     */
    public static List<System.ExternalService.PetstoreService.Pet> getPetsByStatus(String status) {
        List<System.ExternalService.PetstoreService.Pet> pets = new List<System.ExternalService.PetstoreService.Pet>();
        
        // try-catch ブロックで外部サービス呼び出しをラップし、エラーハンドリングを行う
        try {
            // 外部サービスアクションを呼び出すためのリクエストオブジェクトを作成
            // `PetstoreService` は登録したExternal Serviceの名前、`listPets_IN` は生成される入力クラス
            System.ExternalService.PetstoreService.listPets_IN input = 
                new System.ExternalService.PetstoreService.listPets_IN();
            
            // クエリパラメータ `status` を設定。OpenAPI仕様で定義された入力プロパティ
            input.status = new List<String>{status};

            // 外部サービスアクションを実行
            // `listPets` は OpenAPI 仕様の operationId に基づいて生成されたメソッド
            System.ExternalService.PetstoreService.listPets_OUT output = 
                System.ExternalService.PetstoreService.listPets(input);

            // レスポンスを処理
            // 成功レスポンス (200 OK) の結果は `response_200` プロパティに格納される
            if (output != null && output.response_200 != null) {
                System.debug('Successful response for status ' + status + ': ' + output.response_200);
                pets.addAll(output.response_200); // 取得したペットをリストに追加
            } 
            // その他のレスポンス (エラーなど) の処理
            else if (output != null && output.response_default != null) {
                System.debug('Error response for status ' + status + ': ' + output.response_default);
                // エラーレスポンスの詳細をログ出力または適切に処理
            } else {
                System.debug('Unexpected empty response for status ' + status);
            }

        } catch (Exception e) {
            // 外部サービス呼び出し中に発生したシステムエラーをキャッチ
            System.debug('External Service Callout Error for status ' + status + ': ' + e.getMessage());
            // エラーの詳細な情報を得るために ServiceManager を使用することも可能
            // 例: System.ExternalService.ServiceManager.getLastCalloutResponse(e);
        }
        return pets;
    }

    // デモ目的の実行メソッド
    public static void executeExample() {
        List<System.ExternalService.PetstoreService.Pet> availablePets = getPetsByStatus('available');
        System.debug('Available Pets Found: ' + availablePets.size());
        for(System.ExternalService.PetstoreService.Pet pet : availablePets) {
            System.debug('  - Pet ID: ' + pet.id + ', Name: ' + pet.name + ', Status: ' + pet.status);
        }
        
        List<System.ExternalService.PetstoreService.Pet> soldPets = getPetsByStatus('sold');
        System.debug('Sold Pets Found: ' + soldPets.size());
    }
}

このコードは、PetstoreService という名前で External Service が登録されていることを前提としています。System.ExternalService.PetstoreService.listPets_INSystem.ExternalService.PetstoreService.listPets_OUT、そして System.ExternalService.PetstoreService.Pet といったクラスは、External Service の登録時に Salesforce によって自動生成されます。


注意事項とベストプラクティス

権限要件

  • Named Credential へのアクセス権限:Named Credential に関連付けられたプロファイルまたは権限セットに、その Named Credential を参照する権限が付与されている必要があります。
  • External Service の実行権限:フローから External Service を呼び出すユーザーには「フローの実行 (Run Flows)」権限が必要です。Apex から呼び出す場合は、通常、Apex の実行権限(`Apex Callouts`)が含まれるため追加の設定は不要ですが、Named Credential へのアクセス権限は必要です。

Governor Limits

  • Apex Callouts の制限:1つのトランザクション内で最大100回のコールアウト実行、合計120秒のタイムアウト制限があります。External Services も内部的には Apex Callouts を使用するため、これらの制限が適用されます。
  • Named Credential の非同期呼び出し制限:各組織は1日あたり最大 250,000 回の非同期 Named Credential 呼び出しを実行できます(Salesforce Connect の外部オブジェクトからの呼び出しを含む)。この制限に達すると、それ以上の呼び出しは失敗します。
  • CPU Time Limit:大規模なリクエスト/レスポンスの処理は、Apex の CPU Time Limit に影響を与える可能性があります。

エラー処理

  • try-catch ブロックの使用:外部サービス呼び出しはネットワークエラーや外部サービスの応答エラーなど、さまざまな問題が発生する可能性があります。Apex で呼び出す際は必ず try-catch ブロックでラップし、例外を適切に処理してください。
  • エラーレスポンスのハンドリング:外部サービスからのエラーレスポンス(例: HTTP 4xx, 5xx ステータスコード)も Apex の System.ExternalService.ServiceManager.getLastCalloutResponse(Exception) や、External Service 自動生成クラスの response_default プロパティなどを通じて取得し、ビジネスロジック内で適切に分岐・対応することが重要です。
  • フォールバックメカニズム:外部サービスが利用できない場合に備え、代替処理や再試行メカニズム(指数バックオフなど)の実装を検討してください。

パフォーマンス最適化

  • 必要なデータのみ取得:外部サービスにリクエストする際に、必要最低限のデータのみを要求するようにパラメータを最適化し、レスポンスペイロードのサイズを最小限に抑えます。
  • 非同期処理の活用:大量のコールアウトや時間がかかる処理は、Queueable Apex や Batch Apex、Scheduled Apex などの非同期 Apex を利用して実行し、同期処理のガバナ制限を回避し、ユーザーエクスペリエンスを向上させます。
  • キャッシュの利用:頻繁にアクセスされるがめったに変わらないデータは、Platform Cache や静的リソース、カスタム設定などでキャッシュすることを検討し、外部サービスへの不必要なコールアウトを減らします。
  • 外部APIの監視と最適化:Salesforce 側のパフォーマンスだけでなく、連携する外部 API 自体の応答時間や可用性を監視し、ボトルネックが外部サービス側にある場合は、そちらの最適化を働きかけることも重要です。

よくある質問 FAQ

Q1:External Services を登録するための OpenAPI 仕様は、どのようなバージョンや形式をサポートしていますか?

A1:Salesforce External Services は、OpenAPI 2.0 (旧称 Swagger 2.0) および OpenAPI 3.0 の仕様をサポートしています。ファイル形式としては、JSON または YAML のいずれかを使用できます。API の複雑性に応じて、これらの仕様を適切に作成または調整する必要があります。

Q2:External Services を利用した外部 API 呼び出しのデバッグはどのように行いますか?

A2:デバッグには、主に2つの方法があります。まず、Apex コードから呼び出す場合は、デバッグログの `Apex Callout` カテゴリを有効にし、`System.debug()` ステートメントでリクエスト/レスポンスの内容を詳細に出力します。また、Named Credential の詳細設定で「コールアウトログ本文の有効化 (Enable Callout Log Body)」をチェックすることで、HTTP リクエストとレスポンスの本文をデバッグログに記録させることができます(ただし、セキュリティとデータ量に注意が必要です)。

Q3:External Services のパフォーマンスを監視するツールはありますか?

A3:Salesforce Platform では、Event Monitoring を使用してコールアウトイベント(`API Total Usage` イベントタイプなど)を監視し、External Services 経由の呼び出し数や成功/失敗率を追跡できます。また、Transaction Security Policy を設定することで、特定の条件(例:異常な量のコールアウト)で通知を受け取ることも可能です。外部サービス側のパフォーマンス監視は、その外部サービスが提供する監視ツールやログを活用することが重要です。


まとめと参考資料

Salesforce External Services は、OpenAPI 仕様を基盤として、外部サービスとのインテグレーションを劇的に簡素化する強力な機能です。コード記述量を削減し、開発者がビジネスロジックに集中できるようにすることで、開発の迅速化と保守性の向上に貢献します。Named Credential による安全な認証情報の管理、Flow Builder や Apex からの柔軟な利用は、Salesforce エコシステムにおける外部連携の標準的なアプローチとしてその価値を高めています。

この技術を最大限に活用するためには、OpenAPI 仕様の適切な理解、Governor Limits の考慮、そして堅牢なエラー処理とパフォーマンス最適化のベストプラクティスが不可欠です。

公式リソース

コメント