tyoshikawa1106のブログ

- Force.com Developer Blog -

SFDC:Apex開発とPardot API - Part 2

Apex開発とPardot API - Part 2です。Part1ではVisualforceとApexでシンプルなAPI処理の書き方について記載しました。今回はApexバッチによる大量データ処理の場合について紹介します。前回の内容はこちら。

Apexバッチの処理内でAPIを実行する場合は『Database.AllowsCallouts』の宣言が必要になります。

f:id:tyoshikawa1106:20200915084041p:plain


あとは通常のバッチ処理の開発と同じ流れで実装を進められます。

  1. コンストラクタ: 最初に実行される処理。
  2. startメソッド : コンストラクタの次の処理。対象レコード取得クエリを実行。
  3. executeメソッド : メインの処理。レコード件数分繰り返し実行される。
  4. finishメソッド : 一番最後に実行される処理。


ですが、何も考えずに実装すると不要なAPI消費が発生してしまうのでひと手間加えるといいと思います。下記のような感じです。

コンストラクタ

コンストラクタは処理の一番はじめに実行される処理です。ここでカスタム設定に必要な値が存在しているかなどのエラー判定を行います。
f:id:tyoshikawa1106:20200915084140p:plain

コンストラクタでチェックすること
  1. カスタム設定の値チェック
  2. 対象データの存在チェック★
  3. Pardot APIキーの取得(Salesforce APIの実行)
  4. 実行結果を変数にセット

特に重要と考えているのは対象データの存在チェックです。バッチ処理ではstartメソッド内でクエリを実行して0件の場合は処理がスキップされますので通常は気にしなくていいのですが、API処理の実行がある場合、0件で処理を実行しても無意味なため、一度対象が0件がどうかはチェックを行い、処理対象となるデータが存在しない場合は以降の処理をスキップする判定を行っておくと良いと思います。


カスタム設定の存在チェックやPardot APIキーの取得処理でエラー発生した際にはStirng型変数(errorMessage)に原因のテキストを格納してreturnで処理を終了します。このエラーメッセージを格納した変数は以降の処理に引き継いで使用します。


尚、Apexバッチ開発の注意点としてコンストラクタ内でreturn処理を実行して処理を途中で終了しても必ずstartメソッドの処理が実行されます。(Exceptionエラーになれば別です)。そのことを考慮して実装をすすめる必要があります。

startメソッド

startメソッドではバッチ処理の対象となるレコード取得を行います。
f:id:tyoshikawa1106:20200915084901p:plain


startメソッド内でSOQLクエリを実行する際ですが、コンストラクタで用意したエラーメッセージのチェックと対象レコード0件かどうかのSkipフラグの値を確認します。


続きの処理を実行する必要がなければ「LIMIT 0」でバッチ処理をクローズします。
f:id:tyoshikawa1106:20200915085133p:plain

executeメソッド

executeメソッドはバッチ処理のメイン処理です。実行時に指定したバッチサイズの数にレコードを分割して処理を行ってくれます。
f:id:tyoshikawa1106:20200915190540p:plain


基本的に更新用リストに格納して一括更新する処理が望ましいのですが、実行するPardot APIの処理内容によっては一括更新用のAPIが用意されていない場合があります。そうした場合はバッチサイズを制御して処理をするといいと思います。(バッチサイズ200で処理してエラーになるものが、50に設定すると負荷なく処理が実行されるといったケースがありました。ただしバッチサイズ「1」は可能な限り避けたほうが良いと思います。)

finishメソッド

finishメソッドはバッチ処理の一番最後に実行される処理です。エラーが発生している場合などにメール送信処理を実行したりといった使い方ができます。
f:id:tyoshikawa1106:20200915190937p:plain



上記のような感じでPardot APIのバッチ処理による実行が開発可能となっていました。

Pardot APIとスケジュールバッチ

定期的にバッチ処理を実行するにはスケジュールバッチの処理で実現できます。ただし、API処理を含むApexバッチはスケジュールバッチから呼び出すことができません。確か下記のエラーとなります。

callout from scheduled apex not supported


@futureによる非同期処理が回避策としてあったと思いますが、バッチ処理で非同期処理を呼び出すのはあまり適切ではなさそうです。(finish処理の順序も担保されなくなりそう。)


そこで取れる回避策が「Queueable」インターフェースをつかった処理です。


implements Queueableを宣言することで利用できるようになります。

f:id:tyoshikawa1106:20200915192536p:plain

クラスの構成はコンストラクタとexecuteメソッドの2つだけとなります。バッチと似たような感じで開発することになりますが、大量件数の処理には向いていません。


尚、Queueableインターフェースのクラスは下記のような処理で実行します。

System.enqueueJob(new PardotRelationQueueable());


以上がPardot APIでのApexバッチによる大量データの処理とQueueableインターフェースによるスケジュール実行の開発例です。API処理は一日の実行回数に上限がありますので対象データが無い場合は処理スキップするなどひと手間加えて考慮することでトラブルや拡張性の低下を防止することができます。