Salesforce 外部サービスの徹底解説:開発者向け宣言的 REST API 連携ガイド

背景と応用シナリオ

Salesforce 開発者として、私たちは日常的に外部システムとの連携という課題に直面します。従来、外部の REST API を呼び出すためには、Apex で多くの定型的なコード(ボイラープレートコード)を作成する必要がありました。具体的には、HTTP リクエストの作成、認証ヘッダーの設定、JSON のシリアライズ・デシリアライズ、レスポンスの解析、エラーハンドリングなど、多くのステップが含まれます。これらの作業は時間がかかるだけでなく、ヒューマンエラーが発生しやすい領域でもあります。

ここで登場するのが External Services (外部サービス) です。External Services は、OpenAPI 仕様に基づいて外部の REST API を宣言的に Salesforce に統合するための強力な機能です。開発者は、API の仕様ファイルを提供するだけで、Salesforce が自動的に対応する Apex クラスと呼び出し可能なアクションを生成してくれます。これにより、複雑な Apex Callout のコードを一行も書くことなく、Flow や Apex から直接外部 API を呼び出すことが可能になります。

応用シナリオ

External Services は、以下のような多様なシナリオでその真価を発揮します。

・リアルタイムのデータ照会: 顧客の与信スコアを外部の金融サービス API から取得する、あるいは荷物の追跡情報を物流会社の API からリアルタイムで取得するケース。

・外部システムへのデータ送信: Salesforce で新規の注文が作成された際に、その情報を外部の在庫管理システムや ERP システムにリアルタイムで送信するケース。

・業務プロセスの自動化: 住所情報を入力した際に、外部の住所クレンジング API を呼び出してデータを正規化し、Salesforce のレコードを更新するプロセスを Flow で自動化するケース。

・マイクロサービス連携: 社内のマイクロサービスアーキテクチャと Salesforce を連携させ、特定のビジネスロジックを外部サービスとして呼び出すケース。

このように、External Services は開発の生産性を劇的に向上させ、ローコードツール(Flow)とプロコード(Apex)の橋渡し役として、より迅速で堅牢なインテグレーションを実現します。


原理説明

External Services の中核をなすのは OpenAPI Specification (OpenAPI 仕様) です。OpenAPI は、REST API を記述するための標準的な仕様であり、JSON または YAML 形式で記述されます。External Services は、この仕様ファイルを解釈し、Salesforce プラットフォーム上でネイティブに動作するコンポーネントを生成します。

その仕組みは、以下のステップで構成されています。

1. OpenAPI 仕様の登録

まず、連携したい外部 API の OpenAPI 2.0 (Swagger) または OpenAPI 3.0 の仕様ファイルを用意します。このファイルには、API のエンドポイント、利用可能な操作(GET, POST, PUT, DELETE など)、各操作の入力パラメータ、そしてレスポンスのデータ構造(スキーマ)が詳細に定義されています。開発者はこの仕様ファイルを Salesforce の「設定」メニューから External Services に登録します。

2. Apex クラスの自動生成

仕様が登録されると、Salesforce はバックグラウンドで仕様を解析し、対応する Apex クラスを自動的に生成します。これらのクラスは ExternalService という特別な名前空間に格納されます。例えば、`BankService` という名前でサービスを登録した場合、`ExternalService.BankService` のようなクラスが生成されます。このクラスには、OpenAPI 仕様で定義された各操作に対応するメソッドや、リクエストとレスポンスのデータ構造を表す内部クラスが含まれています。

3. 呼び出し可能なアクションの作成

生成された Apex クラスのメソッドは、Invocable Actions (呼び出し可能なアクション) としてプラットフォームに公開されます。これにより、これらの API 操作を Flow の「アクション」要素や、Apex の `Invocable.Action` クラスから簡単に呼び出すことができるようになります。これにより、管理者やコンサルタントも、コーディングなしで外部 API 連携を含む複雑なビジネスプロセスを構築できます。

4. 認証の処理

外部 API との通信には通常、認証が必要です。External Services は Salesforce の Named Credential (指定ログイン情報) と緊密に連携しています。OpenAPI 仕様を登録する際に、対応する Named Credential を選択することで、認証情報をコードから分離し、安全に管理することができます。API キー、OAuth 2.0 など、様々な認証方式を Named Credential 側で設定できるため、Apex コード内で認証情報をハードコーディングする必要がなくなります。

この一連のプロセスにより、開発者は API 連携の本質的な部分、つまり「どのデータを」「いつ」「どのように」送受信するかに集中でき、通信プロトコルやデータ変換といった低レベルの実装から解放されるのです。


示例代码

ここでは、銀行口座情報を管理する架空の銀行サービス API を External Services で登録し、それを Apex から呼び出す例を見てみましょう。この例は Salesforce の公式ドキュメントに基づいています。

まず、`BankService` という名前で以下の操作を持つ OpenAPI 仕様を登録したと仮定します。

  • `accountDetails`: 口座の詳細情報を取得する (GET)
  • `addAccount`: 新しい口座を追加する (POST)

このサービスを Apex から呼び出すコードは以下のようになります。

// BankService という名前の外部サービスを呼び出す Apex の例
public class BankServiceApex {

    // 新しい口座を追加するメソッド
    public static void addAccount() {

        try {
            // 1. 外部サービスによって自動生成されたクラスのインスタンスを作成します。
            // 構文は ExternalService.{外部サービス名} です。
            ExternalService.BankService bank = new ExternalService.BankService();

            // 2. addAccount 操作への入力パラメータを準備します。
            // 自動生成されたリクエスト用の内部クラス `addAccount_Request` を使用します。
            ExternalService.BankService.addAccount_Request request = new ExternalService.BankService.addAccount_Request();

            // 3. リクエストボディのデータを準備します。
            // OpenAPI 仕様で定義された `account` オブジェクトに対応する内部クラスを使用します。
            ExternalService.BankService.account newAccount = new ExternalService.BankService.account();
            newAccount.name = 'Salesforce DX';
            newAccount.accountType = 'Checking';

            // リクエストボディに `account` オブジェクトを設定します。
            request.body = newAccount;

            // 4. 外部サービスの `addAccount` メソッドを呼び出します。
            // この呼び出しが実際の API Callout となります。
            // レスポンスは、自動生成されたレスポンス用の内部クラス `addAccount_Response` に格納されます。
            ExternalService.BankService.addAccount_Response response = bank.addAccount(request);

            // 5. レスポンスを処理します。
            // HTTP ステータスコードが 201 (Created) の場合
            if (response.Code == 201) {
                // レスポンスボディから口座情報を取得します。
                ExternalService.BankService.account returnedAccount = response.Body;
                System.debug('Account Name: ' + returnedAccount.name);
                System.debug('Account Type: ' + returnedAccount.accountType);
            } else {
                // 成功しなかった場合の処理
                System.debug('API call failed with status code: ' + response.Code);
            }

        } catch (Exception e) {
            // 6. 例外処理。API 呼び出し中に発生したエラー(ネットワークエラー、タイムアウトなど)を捕捉します。
            System.debug('An error occurred: ' + e.getMessage());
        }
    }
}

このコードからわかるように、開発者は `HttpRequest` や `HttpResponse` を直接扱う必要がありません。External Services が生成した型付けされたクラス(`BankService.addAccount_Request`, `BankService.account` など)を利用することで、コンパイル時の型チェックの恩恵を受けながら、直感的かつ安全に API 連携を実装できます。


注意事项

External Services は非常に便利ですが、利用する上でいくつか注意すべき点があります。

権限

External Services の設定や Apex からの呼び出しには、適切な権限が必要です。 ・設定時: 「アプリケーションのカスタマイズ」権限が必要です。 ・実行時: 外部サービスを呼び出すユーザには、対象の Named Credential へのアクセス権限と、もしあれば生成された Apex クラスへのアクセス権限が必要です。

API 制限

・コールアウト制限: External Services を経由した API 呼び出しも、Salesforce のガバナ制限(1 トランザクションあたりのコールアウト回数や合計タイムアウト時間)の対象となります。大量のデータを扱うバッチ処理などで利用する際は、これらの制限に抵触しないよう設計に注意が必要です。

・OpenAPI 仕様のサポート範囲: External Services は OpenAPI 2.0 および 3.0 の多くの機能をサポートしますが、一部サポートされていない構文も存在します。例えば、`oneOf`, `anyOf`, `not` といった複雑なスキーマ構成や、一部の再帰的なスキーマ定義はサポートされていません。仕様を登録する前に、Salesforce のドキュメントでサポート範囲を確認することが重要です。サポートされていない仕様を利用しようとすると、登録時にエラーが発生します。

エラーハンドリング

サンプルコードにも示した通り、API 呼び出しは常に成功するとは限りません。ネットワークの問題、外部サーバーのダウン、不正なリクエストデータなど、様々な理由で失敗する可能性があります。そのため、Apex から呼び出す場合は、必ず `try-catch` ブロックを使用して例外を捕捉し、適切なフォールバック処理やエラーロギングを実装する必要があります。Flow から呼び出す場合は、「障害パス」を適切に設定し、エラー発生時の代替アクションを定義することが不可欠です。

Named Credential の利用

エンドポイント URL や認証情報を Apex コードや設定にハードコーディングすることは、セキュリティ上およびメンテナンス上の観点から絶対に避けるべきです。必ず Named Credential を使用し、認証情報とエンドポイントを一元管理してください。これにより、サンドボックスから本番環境への移行や、認証情報の更新が容易になります。


まとめとベストプラクティス

External Services は、Salesforce 開発者にとって、外部 REST API との連携を劇的に簡素化し、開発サイクルを短縮するための強力なツールです。宣言的なアプローチにより、定型的なコードの記述を不要にし、開発者はビジネスロジックの実装に集中できます。また、Flow からも呼び出せるため、管理者やビジネスアナリストが API 連携を含む自動化プロセスを構築する道も開かれます。

ベストプラクティス

  1. 常に Named Credential を使用する: 認証情報とエンドポイントの管理を分離し、セキュリティとメンテナンス性を向上させます。
  2. API 仕様をシンプルに保つ: 可能な限り、シンプルで明確な OpenAPI 仕様を使用します。連携に必要な操作とデータ構造のみに絞り込み、不要な定義は削除することで、生成される Apex コードがクリーンになり、管理が容易になります。
  3. 仕様の事前検証: Salesforce に登録する前に、Swagger Editor などの外部ツールを使用して OpenAPI 仕様が有効であることを検証します。これにより、登録時のエラーを未然に防ぐことができます。
  4. 堅牢なエラーハンドリングを実装する: API 呼び出しは失敗する可能性があることを前提に設計します。Apex では `try-catch` を、Flow では障害パスを活用し、ユーザへのフィードバックや再試行ロジックを組み込みます。
  5. バージョン管理を考慮する: 外部 API がバージョンアップされた場合、新しい OpenAPI 仕様で External Services を更新する必要があります。既存のロジックに影響が出ないよう、更新手順を計画し、サンドボックスで十分にテストしてください。
  6. 適切なツールを選択する: External Services は多くのユースケースに適していますが、SOAP API との連携、非常に複雑な認証フロー、または OpenAPI で表現できない独自のプロトコルが必要な場合は、引き続きカスタム Apex Callout の実装が必要になることもあります。状況に応じて最適なツールを選択することが重要です。

External Services を正しく理解し、ベストプラクティスに従って活用することで、Salesforce プラットフォーム上でのインテグレーション開発は、より迅速で、より安全で、よりスケーラブルなものになるでしょう。

コメント