DEV Community

Cover image for SwaggerドキュメントとPostmanコレクションが乖離してしまう原因と解決策
Akira
Akira

Posted on • Originally published at apidog.com

SwaggerドキュメントとPostmanコレクションが乖離してしまう原因と解決策

SwaggerとPostmanの乖離は、レビュー不足ではなく、同じAPI契約を2つの成果物として管理していることが原因です。openapi.yamlでSwagger UIを生成し、Postmanコレクションでテストを実行すると、どちらか一方だけが更新された瞬間にドキュメントとテストが別物になります。この記事では、なぜ乖離が構造的に発生するのか、そしてOpenAPIを単一の情報源としてドキュメント・モック・テストを運用する手順を説明します。仕様からテストを生成する具体的な手順は、OpenAPIテスト生成に関する既存のハウツーを参照してください。

今すぐApidogを試す

💡 Apidogを使用しているチームは、OpenAPIファイルをドキュメント、モック、テストを同時に駆動する単一の成果物として扱います。解決策は、より厳格なレビューではなく、乖離する可能性のある2つ目の成果物をなくすことです。

なぜ2つのファイルは常に乖離するのか

多くのチームは、次の2つを別々に管理しています。

  • Git上のopenapi.yaml
  • テスト用のPostmanコレクション

どちらも同じAPI契約を表すはずですが、保存場所、編集者、更新タイミングが異なります。どちらのツールも、もう一方との整合性を強制しません。

例を見てみます。

バックエンドチームが、必須のreasonフィールドを持つ新しいPOST /payments/refundエンドポイントをリリースします。QAまたはバックエンド開発者は、テストを実行するためにPostmanコレクションへエンドポイントを追加します。一方、openapi.yamlの更新は後回しになります。

数日後、フロントエンド開発者はSwagger UIのドキュメントを見て、reasonなしでAPIを呼び出します。その結果、ドキュメント上は説明されていない400エラーが返ります。

これは怠慢ではありません。根本原因は、2つの成果物の間に結合がないことです。

成果物 更新者 更新トリガー 検証
openapi.yaml APIデザイナー / テックリード 計画されたドキュメント更新 オプションのリンター(例: Spectral)
Postmanコレクション QA / バックエンド開発者 テスト実行が必要なとき 手動レビューまたはなし
Swagger UI表示 YAMLから自動レンダリング YAMLがプッシュされたときのみ 実際のAPIではなくYAMLを反映

Rulesets - Spectralのようなリンターを使えば、OpenAPI仕様内の構文やスキーマ上の問題は検出できます。しかし、Postmanコレクションが別のリクエストを送信しているかどうかは検出できません。

3つのコピー問題

Stoplight、Swagger UI、Wikiなどのドキュメント基盤も併用している場合、API契約のコピーはさらに増えます。

  1. Gitにコミットされたopenapi.yaml
  2. エクスポート・共有されたPostmanコレクション
  3. Stoplight、Swagger UI、Wikiなどで表示されるドキュメント

それぞれが独立して更新されるため、それぞれが乖離ポイントになります。

OpenAPI Specificationは、APIを記述するための仕様です。同期プロトコルではありません。OpenAPIファイルに書いた内容と、Postmanコレクションで送信している内容が一致することを自動的に保証する仕組みはありません。

同じ契約を3か所で管理すると、障害点も3つになります。サービス数やチーム規模が大きくなるほど、手動同期のコストは非線形に増えます。

乖離がテストを静かに壊す方法

SwaggerとPostmanの乖離で厄介なのは、テストが間違っていても成功し続けることです。

たとえば、OpenAPI仕様では必須フィールドが追加されたのに、Postmanコレクションが古いリクエストボディを送り続けるケースです。バックエンドが移行期間中に古い形式も受け入れている場合、Postmanテストは成功します。しかし、その成功は現在の仕様を検証していることを意味しません。

以下は、仕様側でreasonが必須になった例です。

# openapi.yaml - 更新された仕様 (v2)
paths:
  /payments/refund:
    post:
      summary: 返金を申請する
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - transaction_id
                - reason          # v2で追加された新しい必須フィールド
              properties:
                transaction_id:
                  type: string
                  example: "txn_8x9Ka21"
                reason:
                  type: string
                  enum: [duplicate, fraudulent, requested_by_customer]
                  example: "requested_by_customer"
      responses:
        '200':
          description: 返金が開始されました
          content:
            application/json:
              schema:
                type: object
                properties:
                  refund_id:
                    type: string
                  status:
                    type: string
Enter fullscreen mode Exit fullscreen mode

古いPostmanコレクションは、次のようにtransaction_idだけを送る可能性があります。

{
  "transaction_id": "txn_8x9Ka21"
}
Enter fullscreen mode Exit fullscreen mode

バックエンドがreasonにデフォルト値を補完している場合、このテストは成功します。しかし、仕様上はreasonが必須です。フロントエンドが仕様を見て実装したとき、または別の環境で厳密なバリデーションが有効になったときに問題が表面化します。

OpenAPIバリデーターは、仕様内の不整合を検出できます。しかし、仕様とPostmanコレクションが実際に送信するリクエストの差分までは検出できません。

OpenAPI駆動型テストが実際に意味するもの

OpenAPI駆動型テストでは、OpenAPI仕様を信頼できる唯一の情報源として扱います。

つまり、テストは仕様と並行して手書きするのではなく、仕様から派生させます。仕様が変更されると、テストも同じ情報源を参照するため、変更を追跡できます。

これは単に「SwaggerをPostmanにインポートする」こととは異なります。インポートは一度限りのコピー操作です。インポート直後は同期していても、その後のopenapi.yaml変更はPostmanコレクションへ自動反映されません。

仕様ファーストな実行フローは次のようになります。

  1. openapi.yamlを正式なAPI契約としてGitに置く
  2. ツールがそのファイルを読み取る
  3. 同じ仕様からドキュメント、モック、テストケースを生成する
  4. 仕様変更はPRレビューで管理する
  5. 仕様が変更されたら、下流の出力も同じ仕様から更新する
  6. 同期対象となる別個のPostmanコレクションを持たない

OpenAPI駆動型ワークフロー

仕様ファーストのAPI開発では、より広い設計ワークフローを説明しています。この記事では、特にドキュメントとテスト間の乖離に焦点を当てます。

単一の仕様上の実行レイヤーとしてのApidog

Apidogのモデルでは、Git上のOpenAPIファイルを唯一の情報源とし、Apidogをその上の実行レイヤーとして使用します。

基本的な流れは次のとおりです。

  1. openapi.yamlをGitにコミットする
  2. Apidogに仕様を読み込ませる
  3. 同じファイルから以下を生成する
    • インタラクティブなAPIドキュメント
    • モックサーバー
    • テストスイート
  4. 仕様変更時は、OpenAPIファイルを更新する
  5. 下流のドキュメント、モック、テストを同じ仕様から更新する

Apidogの仕様ファーストモード(現在ベータ版)は、このワークフローのために設計されています。個別のコレクションを維持するのではなく、OpenAPIファイルを中心に出力を生成します。

結果として、乖離するPostmanコレクションを持たずに済みます。ファイルは1つだけです。OpenAPI仕様同期ワークフローでは、GitHubに仕様をコミットし、Apidogと整合させる方法を説明しています。

Postman中心のワークフローから移行する場合は、いきなり全体を置き換えるよりも、POCで次の点を検証すると安全です。

  • 既存のスキーマ複雑度をApidogが扱えるか
  • データ駆動型テストシナリオを再現できるか
  • レポートの可視性や権限が組織のアクセスモデルに合うか
  • CI/CDで既存のテスト実行フローに組み込めるか

APIモックも重要です。モックがテストと同じ仕様から派生していれば、フロントエンド開発者が受け取るレスポンスと、テストが検証するレスポンスが一致します。モックの使いどころは、APIモックのユースケースを参照してください。

移行パスの概要

Swagger + Postmanの構成から移行する場合、一括置換ではなく段階的に進めます。

1. 現在の仕様とPostmanコレクションを棚卸しする

まず、openapi.yamlとPostmanコレクションを比較します。

確認する項目は次のとおりです。

  • 仕様に存在するが、Postmanコレクションにないエンドポイント
  • Postmanコレクションに存在するが、仕様にないエンドポイント
  • HTTPメソッドの差分
  • 必須フィールドの差分
  • リクエストボディスキーマの差分
  • レスポンススキーマの差分
  • 認証方式の差分

このステップで、実際にどれだけ乖離しているかが見えます。

2. openapi.yamlを現在のAPI実装に合わせる

次に、OpenAPI仕様を現在の実装に合わせます。

重要なのは、「最初に設計したAPI」ではなく「現在動いているAPI」を記述することです。古い仕様をそのまま単一の情報源にしても、乖離の起点が変わるだけです。

3. 仕様をApidogにインポートする

整合済みのOpenAPI仕様をApidogにインポートします。

ここで、仕様構造から初期テストスイート、ドキュメント、モックを生成します。最初の目的は、既存Postmanコレクションを完全再現することではなく、仕様を中心にした実行レイヤーを作ることです。

4. 1スプリントだけ並行実行する

既存のPostmanコレクションと、Apidogで生成したテストを1スプリント並行して実行します。

比較するポイントは次のとおりです。

  • 失敗するテストの差分
  • カバーされるエンドポイントの差分
  • リクエストペイロードの差分
  • 認証・環境変数の扱い
  • レポートの見やすさ
  • CI実行時の運用負荷

5. Postmanコレクションを段階的に非推奨にする

並行実行で問題が解消できたら、Postmanコレクションを回帰テストの唯一の情報源として使うのをやめます。

最終的には、次の状態を目指します。

  • Git上のopenapi.yamlが唯一の情報源
  • Apidogがドキュメント、モック、テストを生成
  • Postmanは必要に応じて探索的テストに限定
  • 回帰テスト用の契約はOpenAPI仕様から派生

仕様から初期テストコレクションを生成する手順は、OpenAPI仕様からのテストコレクション生成で詳しく説明されています。

比較: デュアルメンテナンス vs. 仕様を情報源とするモデル

側面 Swagger + Postman(デュアルメンテナンス) OpenAPI駆動型(仕様を情報源とする)
乖離のリスク 高い。2つの成果物が独立して更新される 低い。1つの仕様から出力を派生
テストカバレッジの正確性 手動同期の運用に依存 仕様変更を追跡しやすい
新規開発者のオンボーディング 2つのツールと同期ルールを学ぶ必要がある 1つの仕様を中心に理解できる
CI/CD連携 コレクションのエクスポートと管理が必要 Git内の仕様を直接参照しやすい
モックの一貫性 モックを別途維持または再インポートする必要がある テストと同じ仕様から派生
スキーマ変更のコスト 仕様、コレクション、モックをそれぞれ更新 仕様を一度更新

これはPostman自体の問題ではありません。Postmanはコレクションベースのテストや探索的なAPI呼び出しに強みがあります。問題は、Postmanコレクションを派生成果物ではなく、OpenAPI仕様と並行する契約として扱うワークフローです。

よくある質問

なぜSwaggerをPostmanにインポートしても乖離は解決しないのか?

インポートは、その時点のコピーを作るだけです。

インポート後、openapi.yamlとPostmanコレクションは独立した成果物になります。仕様が変更されるたびに再インポートするか、Postmanコレクションを手動編集する必要があります。これはデュアルメンテナンスの問題に戻ることを意味します。

仕様ファーストモデルを採用しながら、探索的テストのためにPostmanを使い続けることはできますか?

はい。仕様ファーストは、Postmanの使用を禁止するものではありません。

おすすめは、役割を分けることです。

  • 回帰テスト・契約テスト: OpenAPI仕様から派生
  • 一度限りの探索的呼び出し: Postmanなどを利用可能

重要なのは、探索的なPostmanコレクションをAPI契約の唯一の情報源としてコミットしないことです。

いつ自分の仕様が実際のAPI実装から乖離したかをどうやって知るのですか?

最も信頼できる方法は、契約テストレイヤーを用意することです。

APIサーバーのテスト時に、着信リクエストと発信レスポンスをOpenAPI仕様に対して検証します。Spectralのようなツールは仕様の内部整合性を検査できますが、実装との乖離を検出するにはランタイム検証が必要です。

SwaggerとPostmanの乖離、仕様と実装の乖離は別の問題です。ただし両方が同時に存在すると、原因の切り分けがさらに難しくなります。

ApidogはPostmanを完全に置き換えるのですか?

チームのワークフローによります。

Apidogは、設計、モック、テスト、ドキュメントを単一のワークスペースで扱います。Postmanの主な用途が契約テストや回帰テストスイートであれば、Apidogでその領域をカバーできます。

一方、CIでPostmanのコレクションランナーを使っている場合や、既存のコレクションスクリプトが大量にある場合は、仕様ファーストの設計ワークフローと並行してPostmanでのテストを続ける選択肢もあります。まずは1スプリントのトライアルで比較するのが現実的です。

もしopenapi.yamlが既に古くなっていたらどうなりますか?

まず仕様を修正する必要があります。

古いopenapi.yamlを唯一の情報源にしても、間違った情報源を中心に運用するだけです。現在のAPI実装と仕様を比較し、実際の挙動を反映するようにYAMLを更新してください。

移行パスの最初の棚卸しステップは、この作業のためにあります。

結論

SwaggerドキュメントとPostmanコレクションが乖離するのは、それらが結合されていない2つの成果物だからです。これはチームの規律ではなく、デュアルメンテナンスワークフローの構造的な問題です。

解決策は、API契約を1つにすることです。

  • Gitにopenapi.yamlを置く
  • それを唯一の情報源として扱う
  • ドキュメント、モック、テストを同じ仕様から生成する
  • 並行して管理するPostmanコレクションを契約の情報源にしない

Apidogをダウンロードし、既存のOpenAPI仕様をインポートしてください。1つのファイルからドキュメント、モック、テストを生成することで、SwaggerドキュメントとPostmanコレクションを別々に同期する運用を減らせます。仕様ファーストモード(現在ベータ版)を評価する場合は、現在の機能範囲とアクセス詳細をApidog仕様ファーストモードのページで確認してください。

Top comments (0)