【Postman × Salesforce】Bulk API 2.0で大量データを一括投入してみた

今回は、Postmanを使ったSalesforceとのOAuth接続から、REST APIによる基本的なデータ操作、Bulk API 2.0を利用した大量データの一括投入まで、実際の操作手順をご紹介します。

はじめに

こんにちは、エンジニアのH.Xです。
最近の案件で、Salesforceの大量データ登録や性能テストを担当する機会がありました。

普段のちょっとした検証ならREST APIで十分ですが、「数万〜数十万件のデータを流し込んで負荷をかけたい!」という時は、やっぱりBulk API 2.0の出番ですよね。

そこで今回は、Postmanを使って「SalesforceとのOAuth接続」から「REST APIの基本操作」、そして「Bulk API 2.0を用いた大量データ投入」まで、実際に手を動かして検証した内容をまとめてご紹介します。

PostmanからSalesforceへのOAuth接続

まずはPostmanからSalesforceに接続するための事前準備です。
Postmanはデスクトップアプリ版とWebブラウザ版のどちらでも利用できますが、今回はデスクトップアプリ版を使用しています。

Salesforce側の設定

Salesforceの [設定] ➔ [外部クライアントアプリケーションマネージャー] から「新規外部クライアントアプリケーション」を作成します。

主に以下の項目を設定します。
・コールバックURL: https://[組織のドメイン].my.salesforce.com/services/oauth2/callback
・選択されたOAuth範囲:
   API を使用してユーザーデータを管理 (api)
   いつでも要求を実行 (refresh_token, offline_access)

※OAuthアクセス許可の設定について
作成後、OAuthポリシー設定で「許可されているユーザー」が「すべてのユーザーは自己承認可能」になっているか確認しておきましょう。
今回は検証のため、プロファイル等への個別権限割り当てが不要なこちらを選択しています。

Postman側の設定

Salesforce側の設定が完了したら、Postman側で認証情報やURLをセットしていきます。

実務運用では、URLなどの可変パラメーターを各リクエストに直接書き込むのではなく、Postmanの環境変数に登録しておくのがスマートです。

環境変数の設定
1.環境の作成:
・Postmanの左側サイドバーから「Environments」タブを選択します。
・「+Create 」ボタンを押下し、環境名に任意の名前(例: Salesforce Dev)を入力します。

2.変数の登録:
・表示されたテーブルに、以下の通り変数名(Variable)と値(Value)を入力して保存します。
 ①
 Variable: instance_url
 Value: 【利用した組織のドメイン】
 ②
 Variable: job_id
 Value: 【空欄】

3.作成した環境の有効化:
・画面右上にある環境選択のドロップダウンメニューを開き、作成したSalesforce Devを選択します。

Authorizationタブでの設定
1.コレクションの作成:
画面左側の「+」ボタンを押して、新しいCollection(リクエストをまとめるフォルダ)を作成します。

2.認可タブの設定:
・作成したCollection の「認可」 タブを開き、認可タイプで 「OAuth 2.0」 を選択します。

3.各項目の入力:
・トークン名: わかりやすい任意の名前(例: PostmanAccessTest)
・コールバックURL: Salesforce側で設定したコールバックURL
・認可URL: {{instance_url}}/services/oauth2/authorize
・アクセストークンURL: {{instance_url}}/services/oauth2/token
・Client ID / クライアントシークレット: Salesforceで作成した外部クライアントアプリケーションの「コンシューマ鍵と秘密」から取得した値を、それぞれ入力します。

4.トークンの取得:
入力後、下部にある 「新しいアクセストークンを取得」 を押します。
Salesforceのログイン画面が表示されたらログインを完了させ、表示されたダイアログで「Use Token」を押して画面を閉じます。

これで、PostmanからSalesforce APIを呼び出すための認証設定は完了です。

まずは基本!REST APIでサクッとSOQL & 複数作成

認証が正常に完了したら、まずはREST APIを使って基本的な動作を確認してみましょう。
今回は、SOQLによるデータ取得と、複数レコードの一括作成を試します。

リクエストの作成

作成したCollectionにマウスカーソルを合わせて「...」 を押下し、「リクエストを追加」 を選択します。
リクエスト名は分かりやすい名前(例: RESTAPIレコード取得)に設定しておきます。

SOQLクエリでデータを取得してみる(GET)

まずは、REST APIを使って取引先レコードを取得してみます。

・メソッド: GET
・URL: {{instance_url}}/services/data/v60.0/query
・クエリパラメーター:
  キー: q
  値: SELECT Id, Name FROM Account

※URLには直接スペースを含めることができないため、Postmanのパラメーターに入力すると自動的にスペースが + に変換されます(例: SELECT+Id,+Name+FROM+Account)。
パラメーターに入力した内容がそのままURLに反映される仕組みになっています。

設定後、「送信」ボタンを押下すると、画面下部にJSON形式で取引先のレコード取得結果が返ってきます。

複数レコードを一括作成してみる(POST)

続いて、REST APIで取引先レコードをまとめて 5 件作成してみます。
通常の /sobjects/Account/ エンドポイントは 1 件ずつの作成ですが、/composite/sobjects を使うことで最大 200 件まで 1 回のリクエストで作成できます。

新しいリクエストを追加し、メソッドをPOSTに変更します。
・URL: {{instance_url}}/services/data/v60.0/composite/sobjects
・「ボディ」 タブを開き、「raw」 ➔ 「JSON」 を選択します。
以下のJSONを入力します:
{
  "allOrNone": true,
  "records": [
    {
      "attributes": { "type": "Account" },
      "Name": "テスト取引先_REST_001"
    },
    {
      "attributes": { "type": "Account" },
      "Name": "テスト取引先_REST_002"
    },
    {
      "attributes": { "type": "Account" },
      "Name": "テスト取引先_REST_003"
    },
    {
      "attributes": { "type": "Account" },
      "Name": "テスト取引先_REST_004"
    },
    {
      "attributes": { "type": "Account" },
      "Name": "テスト取引先_REST_005"
    }
  ]
}
レコード作成用JSON
※allOrNone パラメーターによるトランザクション処理の挙動
"allOrNone": true を指定すると、配列内の5件のうち1件でも入力ルール違反などのエラーがあった場合、全件がロールバックされます。
もし一部の失敗を許容して成功したレコードのみ作成したい場合は、"allOrNone": false に設定します。

「送信」ボタンを押し、レスポンスに5件分のidとsuccess: trueが返ってくれば、レコードの作成は完了です。

リアルタイムで少量のレコードを操作したい場合や、1回のリクエストで複数レコードを処理したい場合は、REST APIが手軽です。

本番!Bulk API 2.0で大量データを一括処理

REST APIは、少量〜数百件程度のデータ操作には便利ですが、数万〜数十万件のデータを一度に投入する性能テストでは、リクエスト数が多くなり、処理に時間がかかってしまいます。
そこで、大量データを非同期で処理できるBulk API 2.0の出番です!

Bulk API 2.0では、1回のジョブで最大150 MBまでのCSVデータをアップロードできます。
今回の検証では、Developer Edition組織を使用しているため、データストレージ容量上限(5 MB)に加え、24 時間あたりの API リクエスト数やBulk APIの処理上限(24時間あたり15,000バッチ)といったガバナ制限を考慮し、5,000 件のデータでテストを行っています。
(実際の案件では、1回のジョブで5,000,000件規模のデータを一括投入しました。)

Postmanでの処理は以下の4つのステップで進めます。

Step 1: ジョブの作成

まずは Salesforce に対して「これから取引先オブジェクトにデータを投入する枠(ジョブ)」を作成します。
・メソッド: POST
・URL: {{instance_url}}/services/data/v60.0/jobs/ingest
・ボディ(raw / JSON):
{
  "object": "Account",
  "contentType": "CSV",
  "operation": "insert",
  "lineEnding": "CRLF"
}
POST用JSON
※lineEndingには、アップロードするCSVファイルの改行コードに合わせてCRLFまたはLFを指定します。
CSVファイルの文字コードはUTF-8を使用します。特に日本語データを扱う場合は、文字化けを防ぐため、文字コードにも注意しましょう。
送信するとレスポンスに id(例: 750XXXXXXXXXXXXXXX)が返ってきます。
このidを環境変数job_idに設定します。
以降のリクエストでは、{{job_id}} を使用します。

Step 2: CSVデータのアップロード

Step 1で作成したジョブに対して、アップロードしたいCSVデータを送信します。
・メソッド: PUT
・URL: {{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}/batches
・ボディ(バイナリ): ファイルを選択してCSVデータをセットします。
送信すると、ステータスコード201 Createdが返ってきます。

Step 3: CSVアップロードの完了通知

データの送信が終わったら、Salesforce側に「アップロード完了!処理を開始して!」と通知します。
・メソッド: PATCH
・URL: {{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}
・ボディ(raw / JSON):
{
  "state": "UploadComplete"
}
完了通知用JSON

Step 4: 処理ステータスの確認

最後に、Salesforceバックグラウンドでの処理状況を確認します。

・メソッド: GET
・URL: {{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}

レスポンスに含まれる以下の項目を確認します:
・state: ジョブの処理状態
・numberRecordsProcessed: 処理された合計件数
・numberRecordsFailed: 失敗件数

stateがJobCompleteになっていれば、ジョブの処理は完了しています。
numberRecordsFailed が0であれば、レコードの処理に失敗していないことを確認できます。

レコードごとの処理結果を確認したい場合は、以下のエンドポイントにGETリクエストを送信します。
・失敗レコードの確認:
{{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}/failedResults
・成功レコードの確認:
{{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}/successfulResults
・未処理レコードの確認:
{{instance_url}}/services/data/v60.0/jobs/ingest/{{job_id}}/unprocessedRecords
Salesforceの設定画面からも今回の投入結果を実際に確認しましょう。
[設定] ➔ クイック検索で「一括データ読み込みジョブ」を開いてみます。
送信したジョブのステータスや処理件数、処理時間などが一目でわかります。

補足:他の操作(Upsert / Delete / Query)への応用

今回はinsert(新規作成)を例に挙げましたが、Bulk API 2.0では、操作内容を変更することで、更新・削除や大量データの取得にも応用できます。
基本的な流れは、
ジョブ作成 → データ送信 → アップロード完了通知 → ステータス確認
という形で共通しています。

・Upsert(更新・作成):
Step 1のJSONで "operation": "upsert" と指定し、外部 ID 項目名(例: "externalIdFieldName": "My_External_Id__c")を追加します。
CSVにはそのExternal ID列を含めます。

・Delete(削除):
Step 1で "operation": "delete" を指定します。
hardDeleteを指定することで、通常の削除とは異なる削除処理を行うこともできます。

・Bulk Query(大容量データの出力):
データを一括抽出したい場合は、専用の /services/data/v60.0/jobs/queryエンドポイントを使用します。
CSVのアップロードは不要で、Step 1のボディにSOQLを指定してジョブを作成・実行します。

おわりに

今回は、Postmanを使って、SalesforceとのOAuth接続からREST APIの基本操作、そしてBulk API 2.0を利用した大量データ投入までの流れをご紹介しました。

少量のデータをリアルタイムで操作したい場合はREST API、大量のデータを非同期で処理したい場合はBulk API 2.0というように、用途に応じてAPIを使い分けることがポイントです。

Salesforceで大量のテストデータを準備する際や、APIを使ったデータ操作・性能テストを行う際に、本記事が少しでも参考になれば幸いです。