wix-cli-backend-api について
Wix CLI アプリ向けに Astro ルートで HTTP エンドポイントを作成するスキルです。ファイルベースのルーティング、リクエスト処理、公開手順を扱います。
主な機能
- 01Astro ベースの HTTP エンドポイント
- 02ファイルシステムによるルート検出
- 03動的パスパラメーター
- 04HTTP メソッドハンドラー
- 05リクエストとレスポンスの処理
- 06ビルド、プレビュー、公開の手順
活用シーン
- 01Wix CLI アプリの REST API 構築
- 02外部 API やサービスとの連携
- 03フォーム送信やファイルアップロードの処理
- 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 エンドポイントを本番環境で使用するには、プロジェクトをビルドしてリリースします。
buildコマンドを使って、プロジェクトのアセットをビルドします。- 必要に応じて
previewコマンドを使ってプレビュー URL を作成し、テスト用にチームメンバーと共有します。 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コメントは使用しません