どのAPIチームも同じ壁にぶつかります。最初に構築するリクエストは、1つのサーバーに向けられ、1つのトークンがヘッダーに貼り付けられます。次にステージングが登場し、そして本番環境が。突然、実行のたびにURLを手動で編集する羽目になり、基本URLが古いために誰かが本番環境に対して削除エンドポイントをテストしてしまうこともあります。API環境変数は、このような間違いの発生そのものをなくすために存在し、Apidogはそれらを後付けするのではなく、製品の核として組み込んでいます。
このガイドでは、Apidogで開発、ステージング、本番環境をセットアップする方法、トークンとAPIキーをハードコードされた文字列ではなく変数として保存する方法、ローカル値で実際のシークレットをクラウドから切り離す方法、そしてApidog CLIを通じてCIに環境を渡す方法について説明します。APIクライアントが環境とシークレットの管理において何を扱うべきかというより広い視野を知りたい場合は、そちらで別途説明しています。ここでは実践的な内容に焦点を当てます。
ハードコードされたURLとトークンが2番目の環境で問題となる理由
1つの環境であれば、ハードコードは問題なく機能します。`https://api.acmepay.dev`がすべてのリクエストに含まれ、トークンがすべてのAuthorizationヘッダーに含まれていても、まだ何も問題は起きません。
2番目の環境が登場した瞬間に問題が始まります。
- すべてのリクエストはターゲットを変更するために編集が必要です。開発環境に向けられた50のエンドポイントは、ステージングをテストするために50回のURL編集が必要となり、さらに切り戻すために50回以上の編集が必要です。きっとどこかを見落とすでしょう。
- トークンが境界を越えて漏洩します。本番環境のAPIキーがリクエストボディに貼り付けられると、プロジェクトと共に保存され、チームと共有され、コレクションと一緒にエクスポートされます。Twelve-Factor Appの手法はこれについて明確です。設定はデプロイ間で異なり、コードはそうではないため、設定は共有する成果物に含まれるべきではありません。
- 実行の再現性が失われます。URLと認証情報が各リクエスト内に存在する場合、「ステージングに対してスモークテストを実行する」は、ワンクリックの切り替えではなく、手動での検索と置換の儀式になります。
この解決策は古くから確立されています。リクエスト定義(メソッド、パス、ボディ、アサーション)をデプロイメントコンテキスト(ベースURL、認証情報、環境固有のID)から分離することです。リクエストはどこでも同じままで、コンテキストだけが変わります。
Apidogが環境と変数をモデル化する方法
Apidogは問題を連携する2つの部分に分割しています。
環境は、`Dev`、`Staging`、`Prod`のような名前付きのコンテキストです。各環境は独自のベースURL(リクエストが送信されるサーバー)と独自の変数値を持ちます。環境を切り替えると、プロジェクト内のすべてのリクエストはすぐに再ターゲットされます。これは環境管理ドキュメントに記載されています。
変数は、URL、クエリパラメータ、ヘッダー、リクエストボディ、スクリプトなど、値が必要な場所であればどこでも`{{variable_name}}`として参照する名前付きのプレースホルダーです。実行時に、Apidogはアクティブな環境とその他のスコープに基づいてプレースホルダーを解決します。
変数スコープとその優先順位
Apidogは5つのスコープを通じて変数を解決します。優先順位の低い順から高い順に、グローバル、モジュール、環境、データ、ローカルです。
| スコープ | 存在する場所 | 典型的な用途 |
|---|---|---|
| グローバル | プロジェクト全体、すべての環境 | {{api_version}}のような定数 |
| モジュール | プロジェクトの1つのモジュール | マイクロサービスプロジェクトにおけるサービスごとの設定 |
| 環境 | アクティブな環境のみ | {{base_url}}、{{auth_token}}、{{merchant_id}} |
| データ | テスト実行時の外部CSV/JSONファイル | 行ごとのテスト入力 |
| ローカル(一時的) | 1つのリクエストまたはテスト実行、その後消滅 | シナリオ途中で抽出されたトークン |
実際には優先順位が重要です。`{{auth_token}}`をグローバルなフォールバックとして定義するとどこでも機能しますが、`Staging`環境が独自の`{{auth_token}}`を定義すると、`Staging`がアクティブな間は環境値が優先されます。これはまさに意図した動作です。下位には共有のデフォルトがあり、その上に環境固有のオーバーライドがあるのです。各スコープの詳細については、Apidogでの変数の活用に関するガイドをご覧ください。
1つの動作で人々が混乱することがあります。ローカル変数は設計上、一時的なものです。スクリプトで設定すると、実行が完了すると消滅します。これはテストシナリオ内のスクラッチ値のための機能であり、永続すると期待した場合のあなたのメンタルモデルのバグです。明日も必要となるものは、環境変数またはグローバル変数に属します。
Apidogで開発、ステージング、本番環境を設定する
3つのデプロイメントを持つ決済APIのワークフローを以下に示します。
1. 3つの環境を作成する
プロジェクトの右上から環境管理を開き、各デプロイメント用に新しい環境を作成します。それぞれに名前とベースURLを割り当てます。
- `Dev` → `https://api-dev.acmepay.dev`
- `Staging` → `https://api-staging.acmepay.dev`
- `Prod` → `https://api.acmepay.com`
ベースURLはプロトコルで始まり、末尾のスラッシュなしに保ちます。これにより、パスがクリーンに連結されます。
2. 各環境で同じ変数名を定義する
一貫性が最も重要です。すべての環境は、異なる値で同じ変数名を定義します。
| 変数 | Dev | Staging | Prod |
|---|---|---|---|
{{auth_token}} |
devトークン | stagingトークン | prodトークン |
{{merchant_id}} |
mrc_test_449 |
mrc_stg_449 |
mrc_live_8821 |
{{webhook_secret}} |
devシークレット | stagingシークレット | prodシークレット |
3. リクエストで変数を参照し、生の値を決して使用しない
チャージを作成するリクエストは、どこでも次のようになります。
POST /v1/charges
Authorization: Bearer {{auth_token}}
{
"merchant_id": "{{merchant_id}}",
"amount": 1999,
"currency": "usd"
}
ベースURLはまったく表示されません。Apidogはアクティブな環境のベースURLを自動的に前置します。リクエスト定義には環境名は一切含まれておらず、これにより移植性が高まります。
4. セレクターで切り替える
環境セレクターはApidogウィンドウの右上隅にあります。`Staging`を選択すると、プロジェクト内のすべてのリクエスト、テストシナリオ、スクリプトが、ステージングのベースURLとステージングの変数値に基づいて解決されます。編集も検索と置換も必要ありません。どのデプロイメント層に何を置くべきか検討している場合は、サンドボックスとテスト環境の比較で、チームがどのようにそれらを分割しているかを説明しています。
Postmanから移行しますか?既存の環境は引き継がれます。Postman移行ガイドでは、コレクションと環境を数クリックでインポートする方法が、変数値を含めて説明されています。
シークレットをローカルに保持する:共有値とローカル値
これは多くのチームが間違えがちな部分であり、Apidogの設計がその価値を発揮する部分です。
変数リファレンスに記載されているように、Apidogのすべての環境変数とグローバル変数は2つの値を保持できます。
- 共有値: Apidogのサーバーと同期され、プロジェクトの全員に表示されます。
- ローカル値: あなたのマシン上のクライアントのキャッシュにのみ保存されます。クラウドには決して同期されず、チームメイトがそれを見ることもありません。
両方が存在する場合、クライアントはローカル値を使用します。そのため、シークレットの安全なパターンはシンプルです。
- `{{auth_token}}`などの変数を各環境に作成します。
- 共有値を空のままにするか、`SET_LOCALLY`のようなプレースホルダーに設定します。
- あなた自身のマシン上のローカル値に実際のトークンを入れます。
変数構造はチームと同期されますが、シークレットは同期されません。各エンジニアは自分自身の認証情報を一度設定するだけで、すべての共有リクエストがすぐに機能します。これはOWASP Secrets Management Cheat Sheetと一致しています。シークレットのスコープを厳密にし、管理されたチャネルを通じて共有し、広範囲に複製されるものから遠ざけます。
知っておくべき2つの注意点があります。ローカル値はクライアントキャッシュに保存されるため、Apidogのキャッシュをクリアすると削除され、新しいラップトップに移行すると再入力が必要になります。これには5分程度の時間を確保してください。プロダクションキーが12人に同期されたことでインシデントレビューに5時間かかることよりもましです。
また、共有ではなく、環境全体をプライベートとしてマークすることもできます。デプロイを行う2人のみに表示される`Prod`環境は正当な設定であり、多層防御のためにローカル値と組み合わせることができます。
テストシナリオとCIで環境を使用する
環境はApidogのテストシナリオに直接引き継がれます。シナリオを一度構築したら(チャージの作成、ステータスのポーリング、決済のアサート)、実行時にどの環境に対して実行するかを選択します。同じシナリオが開発スモークテストとステージング回帰スイートになります。
スクリプトは同じスコープを読み書きします。ログイン応答から新しいトークンをキャプチャする後処理は次のようになります。
const body = pm.response.json();
pm.environment.set("auth_token", body.access_token);
シナリオ内の後続のリクエストは、`{{auth_token}}`をキャプチャされた値に解決します。リクエストパラメータをスクリプトに取り込むなどのパターンについては、プリ/ポストリクエストスクリプトでのリクエストパラメータの取得をご覧ください。
CIの場合、Apidog CLIは環境をフラグとして受け取ります。
apidog run --access-token $APIDOG_ACCESS_TOKEN \
-t 637132 \
-e 358171 \
--env-var "auth_token=$STAGING_API_TOKEN"
`-e`はIDで環境を選択します。CLIは共有値を解決し、あなたのマシンのローカル値は解決しないことに注意してください。これは正しい動作です。個人のシークレットはビルドエージェントから到達可能であるべきではありません。代わりに、`key=value`形式の`--env-var`と`--global-var`オーバーライド、または`--variables`でファイル全体をロードして、実行時に実際の認証情報を注入します。実際のシークレットはCIプロバイダーのシークレットストア(GitHub Actions secrets、GitLab CI variables)に保存し、それらを通じて渡します。パイプラインには平文のトークンは決して含まれず、認証情報をローテーションすることは1つのCIシークレットを更新するだけで済みます。
ここから生まれるチームワークフロー
これらを組み合わせることで、役割分担が明確になります。
- 共有され、同期されるもの: 環境名、ベースURL、変数名、プレースホルダーの共有値、テストシナリオ。
- 個人的な、ローカルなもの: 各エンジニアのトークンとキーをローカル値として。
- CIが所有するもの: CIシークレットストア内のパイプライン認証情報をCLIフラグを通じて注入。
新しいチームメイトが加わり、プロジェクトを開くと、すべての変数が名前付けされ文書化された3つの準備済みの環境が表示されます。彼らは自身の開発トークンをローカル値フィールドに貼り付けるだけで作業を開始できます。誰も本番キーをDMで送ることはありません。誰も「現在のステージングURL」のWikiページが古くなるのを維持する必要もありません。
避けるべきよくある落とし穴
- 実際のトークンを共有値にコミットすること。これは最もよくある間違いです。シークレットがチームメイトに届く必要がある場合、それはパスワードマネージャーやボールトを介して行われ、同期された変数を介しては行われません。共有値を一度監査してください。ライブ認証情報に見えるものはすべてローカル値に移動し、ローテーションされるべきです。
- アクティブな環境を忘れること。無意識のうちにセレクターを確認せずにリクエストを送信してしまうことがあります。破壊的な操作を誤って実行しにくくしてください。`Prod`はより少ない人にプライベートにし、本番環境専用の変数には明確な名前を付けるか、プレースホルダーの共有値を設定して、間違った環境での実行が静かに成功するのではなく、認証エラーで大々的に失敗するようにします。
- 一時的な変数が永続すると期待すること。実行中に設定されたローカルスコープ変数は、実行が終了すると消滅します。永続的なものはすべてスクリプト内で明示的に環境スコープに昇格させてください。
- 環境間で異なる変数名を使用すること。開発環境では`{{token}}`と呼び、ステージング環境では`{{auth_token}}`と呼ぶ場合、環境を切り替えるとリクエストの半分が機能しなくなります。どこでも同じ名前を使い、値だけを変えてください。
- すべてを1つの巨大な環境に詰め込むこと。`dev_base_url`と`prod_base_url`を単一の環境に詰め込んでいる場合、余計な手間をかけてハードコーディングの問題を再構築していることになります。デプロイメントコンテキストごとに1つの環境にしてください。
これを設定する準備はできていますか?無料でApidogをダウンロードし、3つの環境を作成し、最初のトークンをローカル値に移動させてください。既存のプロジェクトであれば約10分で完了します。
よくある質問
共有Apidogプロジェクトからシークレットをどのように除外しますか?
それらをローカル値として保存します。すべての変数には共有値(チームと同期される)とローカル値(あなたのマシンにのみキャッシュされる)があります。共有値をプレースホルダーのままにして、実際のトークンをローカルに保持します。さらに隔離するため、`Prod`のような機密性の高い環境をプライベートとしてマークし、特定の人だけが見られるようにします。
グローバル変数と環境変数の違いは何ですか?
グローバル変数は、どの環境がアクティブであるかに関わらずプロジェクト全体に適用されます。APIバージョン文字列のように、デプロイ間で変更されない値に使用します。環境変数は1つの環境に属し、両方が同じ名前を定義している場合はグローバル変数よりも優先されます。変数ガイドでは、モジュール、データ、ローカルを含む5つのすべてのスコープについて詳しく説明しています。
Apidogクライアントではテストがパスするのに、CIでは失敗するのはなぜですか?
通常、クライアントがローカル値を解決するのに対し、CLIは共有値を解決するためです。トークンがローカル値にのみ存在する場合、CLIは空またはプレースホルダー変数を参照します。パイプラインで`--env-var "auth_token=$YOUR_CI_SECRET"`を使用して資格情報を明示的に渡すことで、CIが実行時に独自のシークレットを供給するようにします。
Postman環境をApidogに移行できますか?
はい。ApidogはPostmanのコレクションと環境を直接インポートし、変数名と値をそのまま保持するため、移行後も`{{base_url}}`の参照が機能し続けます。インポート後に値を確認し、Postmanのエクスポートにはシークレットが平文で含まれる可能性があるため、実際の認証情報をローカル値に移動させてください。
