DEV Community

Cover image for Apidogでプリリクエスト・ポストレスポンススクリプトを使う方法
Akira
Akira

Posted on • Originally published at apidog.com

Apidogでプリリクエスト・ポストレスポンススクリプトを使う方法

リクエストによっては、送信前の加工やレスポンス受信直後の検証が必要です。たとえばペイメントAPIでは、タイムスタンプと秘密鍵から計算したHMAC署名が必要になります。ログインAPIでは後続リクエストで使うトークンを取得し、チェックアウトAPIでは200と正しい注文IDを確認したいはずです。これを手作業で行うとすぐに再現性がなくなり、チームに共有したときにも壊れやすくなります。Apidogでは、リクエストに小さなJavaScriptスクリプトを追加し、送信前とレスポンス受信後に自動実行できます。Postmanスクリプトを書いたことがある場合、Apidogは同じpmオブジェクトAPIと互換性があるため、既存の知識を活用できます。この記事では、事前スクリプトでHMAC署名を作成し、事後スクリプトでトークンを抽出・検証する実装例を扱います。詳細な仕様はApidogのスクリプトドキュメントも参照してください。

今すぐApidogを試す

事前スクリプトと事後スクリプトの実際の動作

Apidogのスクリプトは、実行タイミングによって次の2つに分かれます。

  • Pre Processors(事前プロセッサー): リクエスト送信前に実行
  • Post Processors(事後プロセッサー): レスポンス受信後に実行

Pre Processorsで行うこと

送信前の準備処理を記述します。

  • タイムスタンプの生成
  • HMACなどの署名計算
  • UUIDや注文IDの生成
  • 環境変数の読み込み
  • ヘッダーやリクエストボディ用の変数設定

この時点ではレスポンスが存在しないため、pm.responseは使用できません。

Post Processorsで行うこと

レスポンスを受け取った後の検証・保存処理を記述します。

  • ステータスコードの検証
  • レスポンスボディのアサーション
  • 認証トークンの抽出
  • 作成されたリソースIDの保存
  • ページネーション用カーソルの保存

重要なのは、pm.responsePost Processorsでのみ使用することです。pm.response.codepm.response.headerspm.response.json()pm.response.text()などは、レスポンス受信後にだけ意味を持ちます。

Pre ProcessorsとPost Processorsの間で値を受け渡すには、変数を使います。

Pre Processorで変数を設定
  ↓
リクエストのヘッダー・URL・ボディで変数を使用
  ↓
Post Processorでレスポンスを検証し、次の変数を保存
Enter fullscreen mode Exit fullscreen mode

Postmanから移行する場合は、タブ名に注意してください。

Postman Apidog
Pre-request Script Pre Processors
Tests Post Processors

セットアップ:リクエストを開き、タブを見つける

Apidogで対象のAPIリクエストを開きます。各エンドポイントには、ParamsHeadersBodyに加えて、次のタブがあります。

  • Pre Processors
  • Post Processors

スクリプトを追加する手順は共通です。

  1. 対象のタブを開く
  2. Custom Scriptを追加を選択する
  3. エディターにJavaScriptを記述する
  4. リクエストを送信して実行結果を確認する

Apidogの変数は、次の優先順位で解決されます。

ローカル変数 > 環境変数 > プロジェクト内で共有されるグローバル変数 > チーム内で共有されるグローバル変数

同じ名前の変数が複数ある場合、より優先順位の高い変数が使われます。期待した値が入らない場合は、ローカル変数や環境変数に同名の値がないか確認してください。

複数リクエストで共有する安定した設定値には、Apidogのグローバルパラメータを使うと便利です。

事前プロセッサーの例:HMACでリクエストを署名する

ここでは、各リクエストにHMAC-SHA256署名を付与するペイメントAPIを例にします。この方式は、Webhook検証などでも使われる一般的なパターンです。署名の考え方はStripeの署名ドキュメントでも確認できます。

この例では、以下を送信します。

  • Unixタイムスタンプ
  • timestamp + 改行 + リクエストボディを秘密鍵でHMAC-SHA256署名した値

1. 環境変数に秘密鍵を設定する

まず、環境変数に次の値を設定します。

payments_api_secret
Enter fullscreen mode Exit fullscreen mode

秘密鍵をスクリプトへ直接書き込まず、環境変数から取得してください。

2. Pre Processorsに署名処理を書く

Pre ProcessorsタブでCustom Scriptを追加し、以下を記述します。

// Pre Processor: リクエストが送信される前に署名します
const CryptoJS = require('crypto-js');

// 現在のUnixタイムスタンプ(秒単位)
const timestamp = Math.floor(Date.now() / 1000).toString();

// 環境変数からシークレットを読み取ります
const secret = pm.environment.get('payments_api_secret');

// 署名する文字列を作成します: タイムスタンプ + 改行 + 生のボディ
const body = pm.request.body ? pm.request.body.toString() : '';
const payload = timestamp + '\n' + body;

// HMAC-SHA256署名を計算し、16進数エンコードします
const signature = CryptoJS.HmacSHA256(payload, secret)
  .toString(CryptoJS.enc.Hex);

// リクエストで利用する環境変数として保存します
pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', signature);

pm.console.log('リクエストを署名しました: ' + timestamp);
Enter fullscreen mode Exit fullscreen mode

Apidogにはcrypto-jsが組み込まれているため、追加インストールは不要です。

3. ヘッダーで変数を参照する

次に、リクエストのHeadersタブで以下を設定します。

X-Timestamp: {{x_timestamp}}
X-Signature: {{x_signature}}
Enter fullscreen mode Exit fullscreen mode

実行順序は次のようになります。

  1. Pre Processorがタイムスタンプを生成する
  2. Pre Processorが署名を計算する
  3. x_timestampx_signatureを環境変数に保存する
  4. Apidogがヘッダー内の{{variableName}}を置換する
  5. 署名済みリクエストを送信する

これにより、毎回有効な署名を手作業なしで送信できます。

require('crypto-js')は使用できますが、require('crypto-js/sha256')のようなサブモジュール指定は使用できません。完全なモジュール名を指定してください。

なお、変数操作は現在の値を対象とし、環境エディターに入力した初期値を書き換えるものではありません。一時的な署名やタイムスタンプには適した挙動です。

Postmanで同様の処理をしている場合は、Postmanの事前リクエストスクリプトも参考になります。

事後プロセッサーの例:トークンを抽出してアサートする

次はログインAPIを例にします。ログイン成功時に、後続リクエストで使用するトークンが返るとします。

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "user": { "id": 4812, "email": "dana@example.com" },
  "expires_in": 3600
}
Enter fullscreen mode Exit fullscreen mode

やりたいことは次の2つです。

  1. レスポンスが期待どおりか検証する
  2. tokenを環境変数に保存する

Post Processorsに検証・保存処理を書く

Post ProcessorsタブでCustom Scriptを追加し、以下を記述します。

// Post Processor: レスポンスを検証し、トークンを抽出します
pm.test('ステータスは200です', function () {
  pm.response.to.have.status(200);
});

const jsonData = pm.response.json();

pm.test('レスポンスはトークンを返します', function () {
  pm.expect(jsonData.token).to.be.a('string').and.not.empty;
});

pm.test('ユーザーIDが存在します', function () {
  pm.expect(jsonData.user.id).to.be.a('number');
});

// 他のリクエストが送信できるようにトークンを保存します
pm.environment.set('auth_token', jsonData.token);

pm.console.log(
  'ユーザー ' + jsonData.user.email + ' のトークンを保存しました'
);
Enter fullscreen mode Exit fullscreen mode

このスクリプトでは、pm.test()pm.expect()でレスポンスを検証しています。成功した場合のみ、トークンを環境変数auth_tokenへ保存します。

後続のAPIリクエストでは、次のようにヘッダーを設定できます。

Authorization: Bearer {{auth_token}}
Enter fullscreen mode Exit fullscreen mode

これでログイン後にトークンをコピー&ペーストする必要がなくなります。

アサーションを増やすことで、目視確認していた作業を自動テストへ置き換えられます。より多くの検証パターンは、ApidogにおけるAPIアサーションを参照してください。

テスト用の入力データを生成したい場合は、ApidogのFaker.jsも変数設定と組み合わせて利用できます。

Post Processorsでの注意点

  • pm.iterationDataは読み取り専用です。テストデータを読み取れますが、スクリプトから書き戻すことはできません。
  • pm.cookiesは、サーバーから返されたレスポンスCookieを返します。リクエスト送信時のCookieではありません。
  • JSON以外のレスポンスでpm.response.json()を呼ぶと失敗するため、必要に応じてContent-Typeやレスポンス形式を確認してください。

公開スクリプトでロジックを再利用する

HMAC署名処理を複数のエンドポイントで使う場合、各リクエストに同じコードをコピーするのは避けるべきです。署名アルゴリズムが変わったときに、複数箇所を修正する必要があるためです。

Apidogでは、Public Scripts(公開スクリプト)を使って共通ロジックを再利用できます。

Public Scriptを作成する

  1. Settings > Public Scriptsを開く
  2. 共通処理をスクリプトとして作成する
  3. 各リクエストのPre ProcessorsまたはPost Processorsに追加する

プロセッサー一覧では、Public ScriptとCustom Scriptが並びます。実行順序が重要です。

  • Public Scriptは、同じ一覧のCustom Scriptより先に実行される
  • Public Scriptが複数ある場合、上から下へ順に実行される

Public Scriptから関数を公開する

Custom ScriptからPublic Scriptの関数を呼び出す場合、その関数はグローバルである必要があります。

以下のように、varletconstを付けずに代入します。

// Public Script内: sign()をグローバルにします
sign = function (payload, secret) {
  const CryptoJS = require('crypto-js');

  return CryptoJS.HmacSHA256(payload, secret)
    .toString(CryptoJS.enc.Hex);
};
Enter fullscreen mode Exit fullscreen mode

その下に配置したCustom Scriptから呼び出します。

// Custom Script内: Public Scriptのグローバル関数を利用します
const timestamp = Math.floor(Date.now() / 1000).toString();
const secret = pm.environment.get('payments_api_secret');

pm.environment.set('x_timestamp', timestamp);
pm.environment.set('x_signature', sign(timestamp, secret));
Enter fullscreen mode Exit fullscreen mode

const sign = ...や通常のローカル関数宣言にすると、次のスクリプトから参照できません。また、Custom ScriptをPublic Scriptより上に置くと未定義関数エラーになります。

ライブラリ、外部パッケージ、およびデバッグ

Apidogには、セットアップ不要で利用できるライブラリが含まれています。これらは通常のrequire()で読み込めます。

  • crypto-js(v3.1.9-1):ハッシュ、HMAC
  • jsrsasign(v10.3.0):JWT、RSA処理(Apidog 1.4.5以降)
  • chai(v4.2.0):アサーション
  • lodash
  • moment
  • uuid
  • xml2js
  • cheerio
  • postman-collection
  • atob
  • btoa
  • csv-parse/lib/sync
  • tv4
  • ajv
  • Node組み込みモジュール(pathassertbufferutilurlquerystringstreameventsなど)

バンドルされていないパッケージを使う

一覧にないnpmパッケージが必要な場合は、$$.liveRequire()を使用します。

$$.liveRequire('nanoid', (nanoid) => {
  const id = nanoid.nanoid();

  pm.environment.set('request_id', id);
});
Enter fullscreen mode Exit fullscreen mode

$$.liveRequire()は実行時にパッケージを取得するため、インターネット接続が必要です。一方、バンドル済みライブラリにはネットワーク接続は不要です。

スクリプトをデバッグする

値を確認したい場合は、pm.console.log()またはconsole.log()を使います。

pm.console.log('timestamp:', timestamp);
pm.console.log('signature:', signature);
console.log('token:', jsonData.token);
Enter fullscreen mode Exit fullscreen mode

出力はApidogのコンソールで確認できます。まずログで値を確認してから、アサーションやシナリオに組み込むとデバッグしやすくなります。

制限事項

pm.sendRequest()はPromiseではなくコールバック形式です。awaitではなくコールバックで扱ってください。

また、Postmanのpm.nextRequest()はサポートされていません。条件分岐や複数リクエストの実行順制御が必要な場合は、テストシナリオを使います。ConditionやIf-Elseステップを使って、リクエストフローを視覚的に構成できます。

Apidog CLIでワークフローを自動化する

Pre ProcessorsとPost Processorsは、画面で「送信」を押したときだけ実行されるものではありません。リクエストとアサーションをテストシナリオとして保存すれば、Apidog CLIでヘッドレス実行できます。

これにより、署名生成・トークン抽出・レスポンス検証をCIに組み込めます。

npm install -g apidog-cli

apidog login --with-token <YOUR_ACCESS_TOKEN>

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <SCENARIO_ID> \
  -e <ENV_ID> \
  -r cli
Enter fullscreen mode Exit fullscreen mode

主なオプションは次のとおりです。

オプション 用途
-t テストシナリオID
-e 環境ID
-r レポーター。clihtmljunitを指定可能

複数のレポーターを使う場合はカンマ区切りで指定します。

apidog run \
  --access-token $APIDOG_ACCESS_TOKEN \
  -t <SCENARIO_ID> \
  -e <ENV_ID> \
  -r cli,junit
Enter fullscreen mode Exit fullscreen mode

アクセストークンはApidogアカウント設定で生成し、CIではAPIDOG_ACCESS_TOKENとして環境変数に設定します。

ただし、ローカルファイルやローカル環境だけに存在する依存関係を使うスクリプトは、デスクトップアプリでは動いてもCLIで失敗する可能性があります。CLIでも同じ動作を保証したい場合は、バンドル済みライブラリまたは$$.liveRequire()で取得できる依存関係に限定してください。

よくある質問(FAQ)

Apidogスクリプトは既存のPostmanスクリプトと互換性がありますか?

多くの場合は互換性があります。Apidogは同じpmオブジェクトAPIを使用するため、次のようなコードはそのまま利用できます。

pm.environment.set('key', 'value');
pm.response.json();
pm.test('テスト名', function () {});
pm.expect(value).to.equal(expected);
Enter fullscreen mode Exit fullscreen mode

主な違いはタブ名です。

  • PostmanのPre-request Script → ApidogのPre Processors
  • PostmanのTests → ApidogのPost Processors

また、pm.nextRequest()など一部のAPIはサポートされていません。

なぜPre Processorsでpm.responseが未定義なのですか?

Pre Processorsはリクエスト送信前に実行されるため、まだレスポンスが存在しないからです。

レスポンスのステータス、ヘッダー、ボディを確認するコードはPost Processorsに書いてください。送信前に必要な情報は、pm.request、変数、またはライブラリから取得します。

1つのスクリプトを複数のリクエストで共有するにはどうすればよいですか?

Settings > Public ScriptsでPublic Scriptを作成し、各リクエストのPre ProcessorsまたはPost Processorsに追加します。

Custom ScriptからPublic Scriptの関数を呼び出す場合は、関数をグローバルとして定義してください。

myFunction = function () {
  // 共通処理
};
Enter fullscreen mode Exit fullscreen mode

また、Public ScriptがCustom Scriptより先に実行されるよう、一覧の順序を確認してください。

Apidogがバンドルしていないnpmパッケージを読み込めますか?

はい。$$.liveRequire()を使います。

$$.liveRequire('package-name', (pkg) => {
  // pkgを使用する
});
Enter fullscreen mode Exit fullscreen mode

実行時にパッケージをダウンロードするため、インターネット接続が必要です。crypto-jsmomentuuidなどのバンドル済みモジュールは、通常のrequire()で読み込めます。

スクリプトの出力はどこで確認できますか?

pm.console.log()またはconsole.log()を使い、リクエスト送信後にApidogのコンソールを確認します。

pm.console.log('計算結果:', value);
Enter fullscreen mode Exit fullscreen mode

署名、トークン、リクエストIDなどを出力すると、スクリプトが期待どおりに動いているかをすばやく確認できます。

まとめ

Pre ProcessorsとPost Processorsを使うと、静的なAPIリクエストを自動化可能なワークフローへ変換できます。

  • Pre Processorsでタイムスタンプ、署名、リクエスト変数を準備する
  • Post Processorsでステータスやレスポンスボディを検証する
  • トークンやIDを環境変数へ保存し、後続リクエストで再利用する
  • 共通処理はPublic Scriptsへ切り出す
  • テストシナリオとCLIでCIへ組み込む

まずはApidogで任意のリクエストを開き、Pre Processorsに1つの変数設定、Post Processorsに1つのアサーションを追加するところから始めてください。

Top comments (0)