zudo-cloudflare-wisdom

Type to search...

to open search from anywhere

Pages Functions

作成2026年4月4日Takeshi Takatsudo

ファイルベースルーティングによるサーバーレス API エンドポイント

概要

Pages Functions は、静的サイトと一緒にデプロイされるサーバーレス関数です。プロジェクトルートの functions/ ディレクトリからファイルベースのルーティングを使用します。

ファイルベースルーティング

ファイルパスが URL に対応します:

functions/api/search.ts      → /api/search
functions/api/users/[id].ts  → /api/users/:id
functions/pj/my-site/api/search.ts → /pj/my-site/api/search

⚠️ パスはデプロイ構造と一致させる

サイトが /pj/my-site/ のようなベースパスを使用している場合、functions ディレクトリもそのパスを反映させる必要があります:functions/pj/my-site/api/search.ts/pj/my-site/api/search で配信されます。

関数のフォーマット

関数は onRequest ハンドラー(またはメソッド固有の onRequestGetonRequestPost など)をエクスポートします:

interface Env {
  KEYWORD_LOGS: KVNamespace;
}

export const onRequestGet: PagesFunction<Env> = async (context) => {
  const url = new URL(context.request.url);
  const query = url.searchParams.get("q");

  // KV バインディングへのアクセス
  const logs = context.env.KEYWORD_LOGS;

  return new Response(JSON.stringify({ results: [] }), {
    headers: { "Content-Type": "application/json" },
  });
};

バインディング

Pages Functions は wrangler.toml で定義されたバインディングを通じて Cloudflare サービスにアクセスします:

compatibility_date = "2024-12-01"

[[kv_namespaces]]
binding = "KEYWORD_LOGS"
id = "abc123def456"

TypeScript コードの Env インターフェースはバインディング名と一致させる必要があります:

interface Env {
  KEYWORD_LOGS: KVNamespace;   // wrangler.toml のバインディング名と一致
  DB: D1Database;              // D1 バインディング
  FILES: R2Bucket;             // R2 バインディング
}

モジュールのインポート

関数は node_modules からインポートできます。ただし、バンドラーの挙動は通常の Node.js とは異なります:

// 動作する -- npm パッケージのインポート
import MiniSearch from 'minisearch';

// 動作する -- JSON のインポート(型安全のため @ts-expect-error を使用)
// @ts-expect-error JSON import bundled by esbuild
import searchData from './search-data.json';

💡 Tip

npm パッケージを必要とする関数の場合、デプロイ前にインストールしておく必要があります。CI での例:

pnpm add -w minisearch  # 依存関係を追加
pnpm dlx wrangler@4 pages deploy deploy --project-name=my-site

ローカル開発

ローカルで関数をテストするには:

npx wrangler pages dev dist --port 8788

これにより、静的ファイルと関数の両方を配信するローカルサーバーが起動します。