mcpField
W
wix-cli-backend-api

wix-cli-backend-api

github.com/wix開発36287 回インストール今日更新
リポジトリ

wix-cli-backend-api について

Wix CLI アプリ向けに Astro ルートで HTTP エンドポイントを作成するスキルです。ファイルベースのルーティング、リクエスト処理、公開手順を扱います。

主な機能

  1. 01Astro ベースの HTTP エンドポイント
  2. 02ファイルシステムによるルート検出
  3. 03動的パスパラメーター
  4. 04HTTP メソッドハンドラー
  5. 05リクエストとレスポンスの処理
  6. 06ビルド、プレビュー、公開の手順

活用シーン

  1. 01Wix CLI アプリの REST API 構築
  2. 02外部 API やサービスとの連携
  3. 03フォーム送信やファイルアップロードの処理
  4. 04バックエンドデータからの動的コンテンツ配信

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/wix/skills --skill wix-cli-backend-api

インストール後、Claude Code で/wix-cli-backend-apiを入力して読み込まれたか確認します。

詳細

Wix Backend API Builder

Wix CLI アプリケーション用の HTTP エンドポイントを作成します。HTTP リクエストを処理し、データを処理してレスポンスを返すサーバー側のルートです。HTTP エンドポイントは Astro エンドポイントを利用し、ファイルシステムから自動的に検出されます。

主な特徴:

  • ファイルは .ts 拡張子で src/pages/api/ に配置します
  • npm run generate では追加できません。ファイルを直接作成してください
  • アプリのダッシュボードの[Extensions]ページには表示されません
  • 拡張機能の登録は不要です(自動検出されます)
  • 以前の Wix CLI for Apps にあった従来の「HTTP functions」に代わるものです

ユースケース

次のような場合に HTTP エンドポイントを使用します。

  • 複数の HTTP メソッドを使った REST API を構築する
  • 外部 API やサービスと連携する
  • 複雑なフォーム送信やファイルのアップロードを処理する
  • 動的なコンテンツ(画像、RSS フィード、パーソナライズされたデータ)を配信する
  • ランタイムデータやサーバー側データベースにアクセスする

ファイル構成と命名

基本的なエンドポイント

ファイルパスによってエンドポイント URL が決まります。

src/pages/api/<your-endpoint-name>.ts
動的ルート

動的パラメーターには角括弧を使用します。

src/pages/api/users/[id].ts → /api/users/:id
src/pages/api/posts/[slug].ts → /api/posts/:slug
src/pages/api/users/[userId]/posts/[postId].ts → /api/users/:userId/posts/:postId

HTTP メソッド

HTTP メソッドごとに名前付き関数をエクスポートします。astro の APIRoute で型を指定します。各ハンドラーは request オブジェクトを受け取り、Response を返します。

import type { APIRoute } from "astro";

export const GET: APIRoute = async ({ request }) => {
  console.log("Log from GET."); // This message logs to your CLI.
  return new Response("Response from GET."); // This response is visible in the browser console
};

export const POST: APIRoute = async ({ request }) => {
  const data = await request.json();
  console.log("Log POST with body: ", data); // This message logs to your CLI.
  return new Response(JSON.stringify(data)); // This response is visible in the browser console.
};

リクエストの処理

パスパラメーター
export const GET: APIRoute = async ({ params }) => {
  const { id } = params; // From /api/users/[id]

  if (!id) {
    return new Response(JSON.stringify({ error: "ID required" }), {
      status: 400,
      statusText: "Bad Request",
      headers: { "Content-Type": "application/json" },
    });
  }

  // Use id to fetch data
};
クエリパラメーター

new URL(request.url).searchParams を使用します。

export const GET: APIRoute = async ({ request }) => {
  const url = new URL(request.url);
  const search = url.searchParams.get("search");
  const limit = parseInt(url.searchParams.get("limit") || "10", 10);
  const offset = parseInt(url.searchParams.get("offset") || "0", 10);

  // Use query parameters
};
リクエストボディ

POST/PUT/PATCH リクエストの JSON ボディを解析します。

export const POST: APIRoute = async ({ request }) => {
  try {
    const body = await request.json();
    const { title, content } = body;

    if (!title || !content) {
      return new Response(
        JSON.stringify({ error: "Title and content required" }),
        {
          status: 400,
          statusText: "Bad Request",
          headers: { "Content-Type": "application/json" },
        }
      );
    }

    // Process data
  } catch {
    return new Response(JSON.stringify({ error: "Invalid JSON" }), {
      status: 400,
      statusText: "Bad Request",
      headers: { "Content-Type": "application/json" },
    });
  }
};
ヘッダー
const authHeader = request.headers.get("Authorization");
const contentType = request.headers.get("Content-Type");

レスポンスのパターン

適切なステータスコードとヘッダーを指定した Response オブジェクトを必ず返します。

// 200 OK
return new Response(JSON.stringify({ data: result }), {
  status: 200,
  headers: { "Content-Type": "application/json" },
});

// 201 Created
return new Response(JSON.stringify({ id: newId, ...data }), {
  status: 201,
  headers: { "Content-Type": "application/json" },
});

// 204 No Content (for DELETE)
return new Response(null, { status: 204 });

// 400 Bad Request
return new Response(JSON.stringify({ error: "Invalid input" }), {
  status: 400,
  statusText: "Bad Request",
  headers: { "Content-Type": "application/json" },
});

// 404 Not Found
return new Response(JSON.stringify({ error: "Not found" }), {
  status: 404,
  statusText: "Not Found",
  headers: { "Content-Type": "application/json" },
});

// 500 Internal Server Error
return new Response(JSON.stringify({ error: "Internal server error" }), {
  status: 500,
  statusText: "Internal Server Error",
  headers: { "Content-Type": "application/json" },
});

フロントエンドとの連携

Wix に組み込まれている HTTP クライアント(httpClient.fetchWithAuth())を使って、フロントエンドコンポーネントから HTTP エンドポイントを呼び出します。

import { httpClient } from "@wix/essentials";

// GET request
const baseApiUrl = new URL(import.meta.url).origin;
const res = await httpClient.fetchWithAuth(
  `${baseApiUrl}/api/<your-endpoint-name>`,
);
const data = await res.text();

// POST request
const res = await httpClient.fetchWithAuth(
  `${baseApiUrl}/api/<your-endpoint-name>`,
  {
    method: "POST",
    body: JSON.stringify({ message: "Hello from frontend" }),
  },
);
const data = await res.json();

ビルド、デプロイ、削除

HTTP エンドポイントを本番環境で使用するには、プロジェクトをビルドしてリリースします。

  1. build コマンドを使って、プロジェクトのアセットをビルドします。
  2. 必要に応じて preview コマンドを使ってプレビュー URL を作成し、テスト用にチームメンバーと共有します。
  3. release コマンドを使って、プロジェクトをリリースします。

リリース後、エンドポイントは本番環境の URL でアクセス可能になり、実際のトラフィックを処理します。

HTTP エンドポイントを削除するには、src/pages/api/ 内のファイルを削除して、再度リリースします。

出力構成

src/pages/api/
├── users.ts              # /api/users endpoint
├── users/
│   └── [id].ts           # /api/users/:id endpoint
└── posts.ts              # /api/posts endpoint

コード品質要件

  • 厳格な TypeScript(any は使用せず、戻り値の型を明示します)
  • すべてのハンドラーで astro の APIRoute を使って型を指定します
  • JSON の場合は JSON.stringify() を使い、必ず Response オブジェクトを返します
  • 適切な HTTP ステータスコード(200、201、204、400、404、500)を使用します
  • JSON レスポンスには Content-Type: application/json ヘッダーを含めます
  • エラーレスポンスには statusText を含めます
  • try/catch ブロックでエラーを処理します
  • 入力パラメーターとリクエストボディを検証します
  • 非同期処理には async/await を使用します
  • @ts-ignore コメントは使用しません

コメント