API開発を加速するPostmanとThunder Clientの使い方

Programming
この記事は約30分で読めます。

こんにちは、JS2IIUです。
API開発において、エンドポイントの動作確認やテストは避けて通れない作業です。しかし、curlコマンドを毎回手打ちしたり、スクリプトを都度書き直したりするのは非効率的ですよね。そこで活躍するのが、PostmanとThunder ClientというAPIクライアントツールです。

本記事では、RESTful APIの開発フローにおいて、これらのツールをどのように活用すれば開発速度を劇的に向上させられるのかを、実践的な例を交えて解説します。環境変数の管理、テストの自動化、そしてCI/CDパイプラインへの組み込みまで、実際の開発現場で使える技術を習得していきましょう。今回もよろしくお願いします。

PostmanとThunder Clientの概要

Postmanとは

Postmanは、API開発のためのオールインワンプラットフォームです。直感的なGUIでHTTPリクエストを作成・送信でき、レスポンスを視覚的に確認できます。チーム開発に強く、APIコレクションの共有機能やモック機能も充実しています。

主な特徴は以下の通りです。

  • リクエストのコレクション管理機能
  • 環境変数による柔軟な設定切り替え
  • JavaScriptベースの自動テスト機能
  • CI/CD連携のためのコマンドラインツール(Newman)
  • チームでのコラボレーション機能

Postman: The World’s Leading API Platform | Sign Up for Free

Thunder Clientとは

Thunder Clientは、Visual Studio Code向けの軽量なAPIクライアント拡張機能です。エディタから離れることなくAPI開発を進められるのが最大の魅力です。Postmanと比較すると機能はシンプルですが、その分動作が軽快で、個人開発や小規模プロジェクトに適しています。本記事作成時点では、Non commercial useのみfreeプランが選べます。

主な特徴は以下の通りです。

  • VS Code内で完結する開発体験
  • 軽量で高速な動作
  • Gitとのシームレスなファイルベースのバージョン管理
  • 環境変数とコレクション管理
  • シンプルなテスト機能

Lightweight Rest API Client Extension for VS Code – Thunder Client

それでは、実際のAPI開発フローに沿って、これらのツールの使い方を見ていきましょう。

実践:FastAPIでのREST API開発フロー

まず、テスト対象となるシンプルなREST APIをFastAPIで構築します。このAPIを通じて、PostmanとThunder Clientの活用方法を学んでいきます。

サンプルAPIの実装

以下は、ユーザー管理を行うシンプルなAPIです。

Python
from fastapi import FastAPI, HTTPException, Header
from pydantic import BaseModel
from typing import Optional, List
import uvicorn

app = FastAPI(title="User Management API")

# データストア(本番環境ではデータベースを使用)
users_db = {}
user_id_counter = 1

# APIキーによる簡易認証
API_KEY = "secret_api_key_12345"

class User(BaseModel):
    name: str
    email: str
    age: Optional[int] = None

class UserResponse(BaseModel):
    id: int
    name: str
    email: str
    age: Optional[int] = None

def verify_api_key(x_api_key: Optional[str] = Header(None)):
    """APIキーを検証する"""
    if x_api_key != API_KEY:
        raise HTTPException(status_code=401, detail="Invalid API Key")
    return x_api_key

@app.post("/users", response_model=UserResponse, status_code=201)
async def create_user(user: User, api_key: str = Header(None, alias="X-API-Key")):
    """新規ユーザーを作成"""
    verify_api_key(api_key)

    global user_id_counter
    user_id = user_id_counter
    users_db[user_id] = user.dict()
    user_id_counter += 1

    return {"id": user_id, **users_db[user_id]}

@app.get("/users", response_model=List[UserResponse])
async def get_users(api_key: str = Header(None, alias="X-API-Key")):
    """全ユーザーを取得"""
    verify_api_key(api_key)

    return [{"id": uid, **udata} for uid, udata in users_db.items()]

@app.get("/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, api_key: str = Header(None, alias="X-API-Key")):
    """特定のユーザーを取得"""
    verify_api_key(api_key)

    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="User not found")

    return {"id": user_id, **users_db[user_id]}

@app.put("/users/{user_id}", response_model=UserResponse)
async def update_user(user_id: int, user: User, api_key: str = Header(None, alias="X-API-Key")):
    """ユーザー情報を更新"""
    verify_api_key(api_key)

    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="User not found")

    users_db[user_id] = user.dict()
    return {"id": user_id, **users_db[user_id]}

@app.delete("/users/{user_id}", status_code=204)
async def delete_user(user_id: int, api_key: str = Header(None, alias="X-API-Key")):
    """ユーザーを削除"""
    verify_api_key(api_key)

    if user_id not in users_db:
        raise HTTPException(status_code=404, detail="User not found")

    del users_db[user_id]
    return None

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

このコードは、CRUD操作を提供する基本的なREST APIです。APIキー認証を実装しており、実際のAPI開発で必要となる認証フローのテストも可能です。APIを起動するには、python api.pyを実行してください。

Postmanでの環境変数管理とコレクション作成

環境変数の設定

API開発では、開発環境、ステージング環境、本番環境など、複数の環境でテストを行う必要があります。Postmanの環境変数機能を使えば、環境ごとの設定を簡単に切り替えられます。

Postmanで環境を作成する手順は以下の通りです。

  1. 左上の環境アイコンから「Environments」を開く
  2. 「Add」ボタンで新しい環境を作成
  3. 環境名を「Development」とする
  4. 以下の変数を追加:
  • base_url: http://localhost:8000
  • api_key: secret_api_key_12345

同様に「Production」環境も作成し、本番環境のURLとAPIキーを設定します。これにより、環境の切り替えがドロップダウンメニューから一発で行えるようになります。

コレクションの作成とリクエストの組織化

次に、APIエンドポイントを整理するためのコレクションを作成します。コレクションは、関連するリクエストをグループ化し、チーム内で共有可能な形式で保存できる機能です。

「User Management API」という名前で新しいコレクションを作成し、以下のリクエストを追加していきます。

ユーザー作成リクエスト

  • Method: POST
  • URL: {{base_url}}/users
  • Headers:
    • X-API-Key: {{api_key}}
    • Content-Type: application/json
  • Body (raw JSON):
JSON
{
  "name": "山田太郎",
  "email": "yamada@example.com",
  "age": 30
}

リクエストを送信すると、作成されたユーザー情報がレスポンスとして返ってきます。このリクエストを保存し、コレクションに追加しましょう。

ユーザー一覧取得リクエスト

  • Method: GET
  • URL: {{base_url}}/users
  • Headers:
    • X-API-Key: {{api_key}}

このように、各エンドポイントに対応するリクエストをコレクションに追加していきます。

自動テストの実装

Postmanの真価は、自動テストスクリプトの実装にあります。Tests タブでJavaScriptを書くことで、レスポンスの検証を自動化できます。

最新版のPostmanではTestsタブからではなく、ポストレスポンススクリプトとして追加する必要があります。

テストはポストレスポンススクリプトの一部になりました

スクリプトを使用してテストやプレリクエストスクリプトを書いたり、レスポンスを視覚化したり、API ワークフローを大幅に自動化したりできます。

ユーザー作成のテストスクリプト

ユーザー作成リクエストの「Scripts」タブに、以下のスクリプトを追加します。

JavaScript
// ステータスコードが201であることを確認
pm.test("Status code is 201", function () {
    pm.response.to.have.status(201);
});

// レスポンスがJSON形式であることを確認
pm.test("Response is JSON", function () {
    pm.response.to.be.json;
});

// レスポンスボディの構造を検証
pm.test("Response has correct structure", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData).to.have.property('id');
    pm.expect(jsonData).to.have.property('name');
    pm.expect(jsonData).to.have.property('email');
    pm.expect(jsonData.id).to.be.a('number');
});

// 作成されたユーザーのIDを環境変数に保存(後続のテストで使用)
pm.test("Save user ID to environment", function () {
    var jsonData = pm.response.json();
    pm.environment.set("created_user_id", jsonData.id);
});

// レスポンス時間が500ms以内であることを確認
pm.test("Response time is less than 500ms", function () {
    pm.expect(pm.response.responseTime).to.be.below(500);
});

このテストスクリプトは、APIが正しく動作していることを多角的に検証します。特に重要なのは、作成されたユーザーIDを環境変数に保存している部分です。これにより、後続のテスト(更新や削除)で同じユーザーを対象にできます。

ユーザー取得のテストスクリプト

個別ユーザー取得リクエスト(GET /users/{{created_user_id}})には、以下のテストを追加します。

Python
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

pm.test("User data matches created user", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData.id).to.eql(parseInt(pm.environment.get("created_user_id")));
    pm.expect(jsonData.name).to.be.a('string');
    pm.expect(jsonData.email).to.include('@');
});

// メールアドレスのバリデーション
pm.test("Email format is valid", function () {
    var jsonData = pm.response.json();
    var emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    pm.expect(jsonData.email).to.match(emailRegex);
});

このように、各エンドポイントに対して適切なテストを実装することで、APIの品質を継続的に保証できます。

Thunder Clientでの軽量開発フロー

VS Codeを使った開発では、Thunder Clientを使うことでエディタから離れずにAPI開発を進められます。

Thunder Clientのセットアップ

  1. VS Codeの拡張機能マーケットプレイスから「Thunder Client」をインストール
  2. サイドバーに稲妻アイコンが表示されるのでクリック
  3. 「Env」タブで新しい環境を作成

環境変数の設定は、Postmanと同様に行います。

JSON
{
  "base_url": "http://localhost:8000",
  "api_key": "secret_api_key_12345"
}

リクエストの作成とテスト

Thunder Clientでは、「New Request」ボタンから新しいリクエストを作成します。Postmanと同様に、URLに{{base_url}}/usersのように環境変数を使用できます。

Thunder Clientのテスト機能は、JSONベースで記述します。「Tests」タブで以下のように設定します。

JSON
{
  "tests": [
    {
      "type": "status-code",
      "value": 201
    },
    {
      "type": "json-query",
      "value": "id",
      "action": "isNumber"
    },
    {
      "type": "response-time",
      "value": 500,
      "action": "lessThan"
    }
  ]
}

Thunder Clientの利点は、すべての設定がファイルとしてプロジェクトディレクトリに保存されることです。.vscode/thunder-client/ディレクトリがGitで管理されるため、チームメンバーと簡単に共有できます。

CI/CDパイプラインへの組み込み

開発したAPIテストをCI/CDパイプラインに組み込むことで、コードの変更ごとに自動的にAPIの動作を検証できます。

Newmanを使ったPostmanコレクションの実行

Newmanは、Postmanコレクションをコマンドラインから実行するツールです。以下のPythonスクリプトで、NewmanをCI/CDパイプラインに統合できます。

JSON
import subprocess
import json
import sys

def run_newman_tests(collection_path, environment_path):
    """
    NewmanでPostmanコレクションを実行し、結果を返す

    Args:
        collection_path: Postmanコレクションファイルのパス
        environment_path: 環境変数ファイルのパス

    Returns:
        テスト結果の辞書
    """
    try:
        # Newmanコマンドを実行
        result = subprocess.run(
            [
                'newman', 'run', collection_path,
                '-e', environment_path,
                '--reporters', 'cli,json',
                '--reporter-json-export', 'newman-results.json'
            ],
            capture_output=True,
            text=True,
            timeout=120
        )

        # 結果ファイルを読み込む
        with open('newman-results.json', 'r', encoding='utf-8') as f:
            results = json.load(f)

        # テスト結果のサマリーを生成
        summary = {
            'total_tests': results['run']['stats']['tests']['total'],
            'passed': results['run']['stats']['tests']['passed'],
            'failed': results['run']['stats']['tests']['failed'],
            'total_requests': results['run']['stats']['requests']['total'],
            'duration': results['run']['timings']['completed']
        }

        print(f"テスト実行完了: {summary['passed']}/{summary['total_tests']} 成功")

        # 失敗したテストがある場合は詳細を表示
        if summary['failed'] > 0:
            print("\n失敗したテスト:")
            for execution in results['run']['executions']:
                for assertion in execution.get('assertions', []):
                    if assertion.get('error'):
                        print(f"  - {assertion['assertion']}: {assertion['error']['message']}")

        return summary

    except subprocess.TimeoutExpired:
        print("エラー: テストがタイムアウトしました")
        sys.exit(1)
    except FileNotFoundError:
        print("エラー: Newmanがインストールされていません")
        print("npm install -g newman でインストールしてください")
        sys.exit(1)
    except Exception as e:
        print(f"エラー: {str(e)}")
        sys.exit(1)

if __name__ == "__main__":
    # コレクションと環境ファイルのパスを指定
    collection = "user_management_api.postman_collection.json"
    environment = "development.postman_environment.json"

    # テストを実行
    results = run_newman_tests(collection, environment)

    # 失敗がある場合は終了コード1で終了(CI/CDでビルド失敗とする)
    if results['failed'] > 0:
        sys.exit(1)

このスクリプトは、Newmanを実行し、テスト結果を解析して表示します。CI/CDパイプラインでこのスクリプトを実行することで、APIの品質を自動的に保証できます。

GitHub Actionsでの自動テスト

.github/workflows/api-test.ymlに以下の設定を追加することで、プルリクエストごとにAPIテストを実行できます。

YAML
name: API Tests

on:
  pull_request:
    branches: [ main, develop ]
  push:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Set up Python
      uses: actions/setup-python@v2
      with:
        python-version: '3.9'

    - name: Install dependencies
      run: |
        pip install fastapi uvicorn
        npm install -g newman

    - name: Start API server
      run: |
        python api.py &
        sleep 5

    - name: Run API tests
      run: |
        python run_newman_tests.py

この設定により、コードがマージされる前に自動的にAPIテストが実行され、問題があればマージをブロックできます。

まとめ

本記事では、PostmanとThunder Clientを活用したAPI開発の効率化手法を解説しました。環境変数による柔軟な設定管理、コレクションを使った組織的なリクエスト管理、JavaScriptによる自動テストの実装、そしてCI/CDパイプラインへの統合まで、実践的な内容をカバーしました。

これらのツールを適切に使い分けることで、API開発の速度と品質を大きく向上させることができます。チーム開発やドキュメント共有が必要な場合はPostman、個人開発や軽量な開発フローを求める場合はThunder Clientといった使い分けを意識すると良いでしょう。

今回紹介したテクニックを実際のプロジェクトに適用し、より効率的なAPI開発を実現してください。最後まで読んでいただきありがとうございました。

コメント

タイトルとURLをコピーしました