DEV Community

Cover image for Zuplo API の使い方
Akira
Akira

Posted on • Originally published at apidog.com

Zuplo API の使い方

Zuploについて調べて実際に何かをデプロイしてみたい開発者向けの実践ガイドです。このプラットフォームは学習が容易ですが、情報がポータル、CLI、ドキュメントに分散しています。この記事では、プロジェクト作成からルート公開、APIキー認証・レート制限追加、カスタムTypeScriptポリシー実装、エッジデプロイ、そしてApidogによるテストまで、必要な手順を網羅します。

今すぐApidogを試す

最終的に、認証・レート制限・自動生成開発者ポータル・CIフレンドリーなGitワークフローを持つAPIゲートウェイが、オリジンサーバーの前段として完成します。このウォークスルー全体は約30分で完了します。

Zuploが適切か迷う場合は、関連投稿「Zuplo APIゲートウェイとは」からご覧ください。エッジケースはZuploドキュメントを参照してください。

TL;DR

  • portal.zuplo.comでサインアップするか、npm create zuploでローカルプロジェクトを作成
  • config/routes.oas.jsonでルートを定義し、URL Forward Handlerでオリジン転送
  • ルートファイルまたはルートデザイナーでAPIキー認証・レート制限などのポリシー追加
  • modules/フォルダでTypeScriptでカスタムロジックを記述
  • Gitブランチにプッシュしてプレビュー環境デプロイ、本番はマージで全世界エッジに配信
  • 本番昇格前にApidogで全ルートテスト
  • 10万リクエスト/月まで無料、ビルダープランは$25/月

前提条件

始めるには以下が必要です。

  • Zuploアカウント
  • オリジンAPI(無ければ https://echo.zuplo.io 利用可)
  • CLI利用時はNode.js 18以上

ローカル開発にはVS Code + TypeScript拡張機能推奨。Apidog VS Code拡張を使うとエディタから直接リクエストを発行できます。

ステップ1:Zuploプロジェクトを作成する

オプションA:ポータル優先

  1. portal.zuplo.com にサインイン
  2. 「New Project」→例: acme-gateway
  3. 「Empty Project」を選択
  4. コードタブでファイルツリーを確認

ポータルはデフォルトでGitリポジトリにリンクされます。後からGitHub等を接続可能です。

オプションB:CLI優先

CLIでローカルにプロジェクトを作成し、IDEで編集・即日Git運用可能です。

npm create zuplo@latest -- --name acme-gateway
cd acme-gateway
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

開発サーバーはポート9000、ルートデザイナーは http://localhost:9100 で利用可能。ホットリロード対応。

Zuploアカウントとリンクするには:

npx zuplo link
Enter fullscreen mode Exit fullscreen mode

プロンプトでアカウント・環境を選択し、npx zuplo deployでGitブランチをデプロイ。

ステップ2:最初のルートを定義する

config/routes.oas.json を編集し、例えば GET /v1/products をオリジンに転送する設定例:

{
  "openapi": "3.1.0",
  "info": { "title": "Acme Gateway", "version": "1.0.0" },
  "paths": {
    "/v1/products": {
      "get": {
        "summary": "List products",
        "operationId": "list-products",
        "x-zuplo-route": {
          "corsPolicy": "anything-goes",
          "handler": {
            "export": "urlForwardHandler",
            "module": "$import(@zuplo/runtime)",
            "options": {
              "baseUrl": "${env.ORIGIN_URL}"
            }
          },
          "policies": { "inbound": [] }
        },
        "responses": {
          "200": { "description": "Success" }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • x-zuplo-routeでZuplo拡張を指定
  • handlerurlForwardHandler(組み込みプロキシ)
  • ${env.ORIGIN_URL} は環境変数から取得

ORIGIN_URLはポータル設定または config/.env で設定。無ければ https://echo.zuplo.io を指定。

保存後、http://localhost:9000/v1/products でリクエストを確認。

ステップ3:APIキー認証を追加する

API公開には認証必須。ZuploのマネージドAPIキーサービスを利用します。

  1. ルートの policies.inbound"api-key-auth" を追加
"policies": {
  "inbound": ["api-key-auth"]
}
Enter fullscreen mode Exit fullscreen mode
  1. config/policies.json にポリシーを定義
{
  "name": "api-key-auth",
  "policyType": "api-key-inbound",
  "handler": {
    "export": "ApiKeyInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "allowUnauthenticatedRequests": false
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. ポータル「Services > API Key Service」でConsumer作成 → APIキー発行

  2. テスト(ヘッダー無しで401, ヘッダー有りで200)

curl -i https://YOUR-PROJECT.zuplo.app/v1/products
# HTTP/2 401

curl -i https://YOUR-PROJECT.zuplo.app/v1/products \
  -H "Authorization: Bearer YOUR_API_KEY"
# HTTP/2 200
Enter fullscreen mode Exit fullscreen mode

クライアントテストはApidogにOpenAPIスペックをインポートし、グローバルヘッダー Authorization: Bearer {{api_key}} を追加するのが効率的です。

ステップ4:ルートのレート制限

公開APIは必ずレート制限を設定しましょう。

  1. policies.inboundにレート制限を追加
"policies": {
  "inbound": ["api-key-auth", "rate-limit-by-key"]
}
Enter fullscreen mode Exit fullscreen mode
  1. config/policies.json に定義
{
  "name": "rate-limit-by-key",
  "policyType": "rate-limit-inbound",
  "handler": {
    "export": "RateLimitInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "rateLimitBy": "sub",
      "requestsAllowed": 60,
      "timeWindowMinutes": 1
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  • rateLimitBy: "sub"でAPIキーごとに60リクエスト/分
  • 匿名制限は "ip" に変更

テスト例(70リクエスト中、60回200、10回429):

for i in {1..70}; do
  curl -s -o /dev/null -w "%{http_code}\n" \
    https://YOUR-PROJECT.zuplo.app/v1/products \
    -H "Authorization: Bearer YOUR_API_KEY"
done | sort | uniq -c
Enter fullscreen mode Exit fullscreen mode

ステップ5:リクエストペイロードを検証する

OpenAPIのJSON Schemaを活用し、リクエストバリデーションをゲートウェイで実施します。

  1. POST /v1/products の例:
"/v1/products": {
  "post": {
    "summary": "Create product",
    "operationId": "create-product",
    "requestBody": {
      "required": true,
      "content": {
        "application/json": {
          "schema": {
            "type": "object",
            "required": ["name", "priceCents"],
            "properties": {
              "name": { "type": "string", "minLength": 1 },
              "priceCents": { "type": "integer", "minimum": 1 },
              "category": { "type": "string", "enum": ["food", "drink"] }
            }
          }
        }
      }
    },
    "x-zuplo-route": {
      "handler": {/* 省略 */},
      "policies": {
        "inbound": [
          "api-key-auth",
          "rate-limit-by-key",
          "validate-request"
        ]
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. policies.json に追加
{
  "name": "validate-request",
  "policyType": "open-api-request-validation-inbound",
  "handler": {
    "export": "OpenApiRequestValidationInboundPolicy",
    "module": "$import(@zuplo/runtime)",
    "options": {
      "validateBody": "reject"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

必須フィールド欠落や不正値で400応答。Apidogを使った正常・異常リクエストのグループテスト推奨。

ステップ6:カスタムTypeScriptポリシーを記述する

ビルトインポリシーで足りない場合は、TypeScriptで拡張可能。例:有料プランは Cache-Control 付与、無料は no-store

modules/tiered-cache.ts:

import { ZuploRequest, ZuploContext, HttpProblems } from "@zuplo/runtime";

interface PolicyOptions {
  paidPlanHeader: string;
  paidMaxAge: number;
}

export default async function (
  response: Response,
  request: ZuploRequest,
  context: ZuploContext,
  options: PolicyOptions,
): Promise<Response> {
  const plan = request.user?.data?.plan ?? "free";

  if (plan === "free") {
    response.headers.set("Cache-Control", "no-store");
  } else {
    response.headers.set(
      "Cache-Control",
      `public, max-age=${options.paidMaxAge}`,
    );
  }

  context.log.info(`Cache header set for plan=${plan}`);
  return response;
}
Enter fullscreen mode Exit fullscreen mode

policies.json に登録:

{
  "name": "tiered-cache",
  "policyType": "custom-code-outbound",
  "handler": {
    "export": "default",
    "module": "$import(./modules/tiered-cache)",
    "options": {
      "paidPlanHeader": "x-plan",
      "paidMaxAge": 300
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

ルートで参照:

"policies": {
  "inbound": ["api-key-auth", "rate-limit-by-key"],
  "outbound": ["tiered-cache"]
}
Enter fullscreen mode Exit fullscreen mode

関数ベースなのでVitest/Jestで単体テスト可能です。

ステップ7:エッジにデプロイする

デプロイはGit操作で完結。

git add .
git commit -m "Add products gateway with auth, rate limit, and tiered cache"
git push origin feature/products-gateway
Enter fullscreen mode Exit fullscreen mode

各ブランチごとにプレビュー環境がURL付きでビルドされます(例: https://acme-gateway-feature-products-gateway-abc123.zuplo.app)。

Apidogでプレビュー環境をフルテスト→OKならマージで本番ロールアウト:

git checkout main
git merge feature/products-gateway
git push origin main
Enter fullscreen mode Exit fullscreen mode

60秒以内に全エッジで新バージョン稼働。ロールバックも git revert だけでOK。

ステップ8:開発者ポータルを生成する

自動生成ポータルは https://YOUR-PROJECT.developers.zuplo.com で公開。特長:

  • 各ルートごとにページ+Tryコンソール
  • cURL/JS/Python/Go等のコードサンプル
  • APIキーのセルフサービス発行
  • Next.jsベースのカスタマイズ可能ソース(GitHubリポジトリ

OpenAPIに説明・例があれば即完成度高いポータルとなります。

ステップ9:Apidogですべてをテストする

本番事故を防ぐには、全ルート・全ポリシー・全エラーパスの自動テストが不可欠。Apidogが迅速に実現します。

おすすめワークフロー:

  1. https://YOUR-PROJECT.zuplo.app/openapi からOpenAPI仕様をインポート
  2. local/preview/production 環境ごとに base_urlapi_key を設定
  3. 各ルートごとに正常/認証失敗/レート制限のリクエストを保存し、グループ実行
  4. Apidog自動テストでシナリオ連結・応答shapeチェック
  5. 必要ならコードスニペットをチームの主要言語で生成

Postmanからの移行はAPIテストガイド参照。Apidogダウンロードも活用ください。

Zuploの使用に関するよくある質問

仕様を変更せずに、環境間でルートを切り替えるには?

環境変数ORIGIN_URLを各環境で設定し、ハンドラーで${env.ORIGIN_URL}参照。ルート定義はそのままでOK。

Zuploをオフラインで実行できますか?

npm run dev でローカルゲートウェイ・デザイナー起動。カスタムポリシー等もローカルで動作。APIキー管理のみクラウド接続が必要で、npx zuplo linkで利用可能。

不正なデプロイをロールバックするには?

git revert → pushでOK。Git履歴が唯一のソース。

デプロイ中のリクエストは?

エッジでアトミックに切り替わるため、進行中のリクエストは旧バージョンで完結。ダウンタイムなし。

gRPCやWebSocketsサポートは?

urlForwardHandlerでWebSocket透過プロキシ。gRPCも専用ハンドラー対応。REST/GraphQLがファーストクラス。

Zuplo APIをAIエージェント向けに公開できますか?

MCPサーバーハンドラー追加&OpenAPI指定で対応。認証・レート制限も適用。詳細はZuplo MCPサーバードキュメント

本番料金は?

無料は月10万リクエスト、ビルダープラン$25/月で100万リクエスト追加、超過は10万ごと$100。エンタープライズは月$1,000~。詳しくは料金ページ

結論

これで、APIキー認証・レート制限・リクエスト検証・カスタムTypeScriptポリシー・開発者ポータル・Gitベースエッジデプロイが可能なZuploゲートウェイの実装が完了です。プレビュー環境、本番ロールアウト、AIエージェント向け公開も同じプロジェクトで管理できます。

安定運用の鍵はテストループです。すべてのプレビュー環境にApidogでテストを実施し、認証・スキーマ・レート制限ミスを本番前に発見しましょう。Apidogをダウンロードして、今すぐゲートウェイに組み込んでください。

Top comments (0)