mcpField
E
edgeone-makers-recipes

edgeone-makers-recipes

github.com/tencentedgeone開発1.8k249 回インストール3 週間前に更新
リポジトリ

edgeone-makers-recipes について

EdgeOne Makers 向けのアプリレシピとプロジェクトテンプレート集です。API 関数、Blob と KV による永続化、各言語の構成、開発プレビューの要件を扱います。

主な機能

  1. 01フルスタックプロジェクトのテンプレート
  2. 02Blob を使った永続化パターン
  3. 03KV を使う Edge Functions の例
  4. 04Node.js、Python、Go のディレクトリ構成
  5. 05開発プレビューとファイル命名のガイド

活用シーン

  1. 01API ルートを備えたサイトの構築
  2. 02動的サイトへの Blob 永続化の追加
  3. 03KV を使ったカウンターの作成
  4. 04言語に応じた関数ディレクトリ構成の選択

インストール

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

$npx skills add https://github.com/tencentedgeone/edgeone-makers-tools --skill edgeone-makers-recipes

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

同梱ファイルreferences/youth-site-scenarios.md

詳細

よく使うレシピ

⛔ プレビュー禁止:開発を終えたら、必ず edgeone makers dev で開発サーバーを起動し、present_files を使って http://127.0.0.1:8088/ を開き、プレビューしてください。file:// プロトコルで HTML ファイルを開かないでください(IDE が自動的に開いた場合も無視してください)。また、python -m http.server や npx serve などのセルフホスト型サーバーは使用しないでください。Next.js プロジェクトでは、next.config に allowedDevOrigins: ["127.0.0.1"] も設定してください。プロジェクトで Blob/KV を使用する場合は、-n <project-name> を渡してください。つまり edgeone makers dev -n <project-name> です。この名前は自動プロビジョニングに必須です。引数なしの dev は、サンドボックスで対話型の選択画面が表示されたまま停止します。

⚠️ .env.example は必須ファイルです:AI Gateway を使用するすべてのプロジェクト(Agent プロジェクト、LLM を呼び出す Cloud Functions)は、プロジェクトのルートに AI_GATEWAY_API_KEY= と AI_GATEWAY_BASE_URL= を宣言した .env.example を必ず作成してください。CLI はデプロイ時にこのファイルに基づいて環境変数を自動注入します。ファイルがない場合、環境変数は注入されず、ランタイムでエラーが発生します。

📝 index.html は必ず最後に作成してください:index.html を作成すると、IDE の file:// プレビューがすぐに起動します。WorkBuddy ではこれを避けられません。このプレビューが壊れて見える時間を最小限にするため、まず依存ファイルをすべて作成してください。style.css、script.js、Cloud Functions(functions/ 内のファイル)、静的アセットなど、ページが読み込むものはすべて先に用意します。その後、index.html を最後に作成してください。file:// プレビューはアセットがすべて揃った状態で開き、edgeone makers dev に引き継がれるまでその状態を保ちます(上記のプレビュー禁止を参照)。また、各 index.html は一度に書き上げてください。空のひな形を作成してから何度も編集して埋めるのは避けてください(保存のたびに再レンダリングされ、ちらつきます)。小さな単一ページのツールなら、CSS と JS を 1 つの index.html にインラインで記述してください。

⛔ レシピに記載されたファイル名をそのまま使ってください。気づきにくい失敗につながる落とし穴が 2 つあります:Cloud Function を作成する前に、以下で該当するシナリオを確認し、正確なファイル名をそのまま使用してください。ファイル名を間違えても、通常は明確なエラーにならず、代わりに暗黙のフォールバックが発生します。

  1. すべての関数ファイルには言語の拡張子が必要です — .js(Node)、.py(Python)、.go(Go)。拡張子のないファイル(例:api/upload-url、api/file)は関数として認識されません。プラットフォームは静的な index.html のフォールバックを暗黙的に配信するため、/api/* が JSON ではなく HTML を「不可解にも」返します。api/upload-url.js、api/file.js のように命名してください。
  2. [[default]].js は、それが置かれたディレクトリ用のキャッチオールです(api/[[default]].js → /api/*)。また、どちらのエクスポート形式も使えます — フレームワークのインスタンス(Express/Koa の export default app)でも、通常の onRequest/onRequestGet/… ハンドラーでもかまいません。edgeone makers dev でローカル検証したところ、[[default]].js 内に export default app がなくても、単独の onRequest で /foo/anything に 200 application/json が問題なく返されました。ドキュメントの 「ビルダーがファイルを関数として認識するのは、export default app がある場合のみ」 という記述は、Express/Koa フレームワークのセクションにあります。これはビルダーがフレームワークのインスタンスを判別する方法を説明しているのであり、「キャッチオールには export default app が必要」という意味ではありません。⚠️ 注意:この記述はデプロイ時のビルダーについてのもので、上記の検証は、より寛容なローカル開発サーバーで行われました。そのため、キャッチオールと onRequest を組み合わせてデプロイする場合は、デプロイ後にルートをもう一度確認してください(「ローカルで動く」ことは「ビルド時に認識される」ことを意味しません)。キャッチオールが不要な場合は、ルートごとに具体的なファイルを 1 つ用意する方法が最も安全です(api/messages.js、api/artworks/[id]/like.js)。パラメーターには [id] フォルダー/ファイルを使い、追加の引数はクエリ文字列で渡します(/api/file?key=...)。

一般的な EdgeOne Makers アプリケーション向けのプロジェクト構成テンプレート。

フルスタックアプリ — Node.js(静的サイト+API)

my-app/
├── index.html              # Frontend
├── style.css
├── script.js
├── cloud-functions/
│   └── api/
│       ├── users.js        # GET/POST /api/users
│       └── users/[id].js   # GET/PUT/DELETE /api/users/:id
└── package.json

フロントエンドから API を呼び出します。

const res = await fetch('/api/users');
const users = await res.json();

💾 データはどこに保存されますか? このプラットフォームにはデータベースがありません。上記の API のひな形は空のデータを返します。レコード、アップロード、投票、ユーザーごとの状態を実際に永続化するには、Blob をバックエンドとして使用してください。以下のレシピと、makers-storage → バックエンドとしての Blob を参照してください。

Blob による永続化を備えた動的サイト(ゲストブック/ギャラリー/投票/状態保存)

リレーショナルデータは不要でも、実際のバックエンドが必要なあらゆる生成サイトに適した基本構成です。フロントエンド → Cloud Function → Blob。データベースもコンソールでの設定も不要です。

my-app/
├── index.html              # Frontend (form + list)
├── script.js
├── cloud-functions/
│   └── api/
│       └── messages.js     # GET lists entries, POST appends one
├── package.json            # depends on @edgeone/pages-blob

cloud-functions/api/messages.js — レコードごとに 1 ファイル(パターン 1):

import { getStore } from "@edgeone/pages-blob";

export async function onRequest({ request }) {
  const store = getStore("guestbook");

  if (request.method === "POST") {
    const { name, text } = await request.json();
    const id = `${Date.now()}-${Math.round(Math.random() * 1e6)}`;
    await store.setJSON(`entries/${id}.json`, { id, name, text, ts: Date.now() });
    return Response.json({ ok: true, id });
  }

  const { blobs } = await store.list({ prefix: "entries/" });
  const items = await Promise.all(blobs.map((b) => store.get(b.key, { type: "json" })));
  items.sort((a, b) => b.ts - a.ts);
  return Response.json({ items });
}

index.html フロントエンドからは、他の API と同じように呼び出します。

await fetch('/api/messages', {                     // post
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ name, text }),
});
const { items } = await fetch('/api/messages').then((r) => r.json());  // list

他のデータ形式では、キーの方式を変更します。状態保存には users/<uid>.json、投票には counts/<option>.json(強い一貫性)、ファイルアップロードには uploads/<id>.jpg + items/<id>.json を使用します。パターンの詳細は、makers-storage → バックエンドとしての Blob を参照してください。

フルスタックアプリ — Go(Gin フレームワーク)

my-app/
├── index.html              # Frontend
├── style.css
├── script.js
├── cloud-functions/
│   └── api.go              # Gin app — all /api/* routes
├── go.mod
└── package.json

cloud-functions/api.go:

package main

import (
    "net/http"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    r.GET("/users", listUsersHandler)
    r.POST("/users", createUserHandler)
    r.GET("/users/:id", getUserHandler)
    r.Run(":9000")
}

フルスタックアプリ — Python(Flask)

my-app/
├── index.html              # Frontend
├── style.css
├── script.js
├── cloud-functions/
│   └── api/
│       └── index.py        # Flask app — all /api/* routes
├── cloud-functions/requirements.txt
└── package.json

cloud-functions/api/index.py:

from flask import Flask, jsonify, request

app = Flask(__name__)

@app.route('/users', methods=['GET'])
def get_users():
    return jsonify({'users': []})

@app.route('/users', methods=['POST'])
def create_user():
    data = request.get_json()
    return jsonify({'message': 'Created', 'user': data}), 201

フルスタックアプリ — Python(FastAPI)

my-app/
├── index.html
├── cloud-functions/
│   └── api/
│       └── index.py        # FastAPI app — all /api/* routes
├── cloud-functions/requirements.txt
└── package.json

cloud-functions/api/index.py:

from fastapi import FastAPI

app = FastAPI()

@app.get('/items')
async def list_items():
    return {'items': []}

@app.get('/items/{item_id}')
async def get_item(item_id: int):
    return {'item_id': item_id}

フルスタックアプリ — Go(ハンドラーモード)

my-app/
├── index.html
├── cloud-functions/
│   └── api/
│       ├── users/
│       │   ├── list.go     # GET /api/users/list
│       │   └── [id].go     # GET /api/users/:id
│       └── hello.go        # GET /api/hello
├── go.mod
└── package.json

エッジ API + KV カウンター

⚠️ 前提条件:コンソールで KV Storage を有効にし、先に名前空間をバインドする必要があります。../makers-storage/references/kv.md を参照してください。

my-app/
├── index.html
├── edge-functions/
│   └── api/
│       └── visit.js        # Edge function with KV
└── package.json

edge-functions/api/visit.js:

export async function onRequest() {
  // ⚠️ my_kv is a global variable (name set when binding namespace in console)
  let count = await my_kv.get('visits') || '0';
  count = String(Number(count) + 1);
  await my_kv.put('visits', count);
  
  return new Response(JSON.stringify({ visits: count }), {
    headers: { 'Content-Type': 'application/json' },
  });
}

セットアップ手順:

  1. EdgeOne Makers コンソールにログインします
  2. 「KV Storage」に移動し、「Apply Now」をクリックします
  3. 名前空間を作成します(例:my-kv-store)
  4. プロジェクトにバインドし、変数名を my_kv に設定します
  5. デプロイするか、edgeone makers dev を実行してテストします

Express フルスタック

my-app/
├── index.html
├── cloud-functions/
│   └── api/
│       └── [[default]].js  # Express app handles all /api/*
└── package.json

ミドルウェア+API の組み合わせ

my-app/
├── middleware.js            # Auth guard for /api/*
├── cloud-functions/
│   └── api/
│       ├── public.js       # No auth needed (matcher excludes it)
│       └── data.js         # Protected by middleware
└── package.json

複数言語の Cloud Functions

同じ cloud-functions/ ディレクトリで、異なる言語を使用できます。

my-app/
├── index.html
├── cloud-functions/
│   ├── api/
│   │   ├── users.js        # Node.js — /api/users
│   │   └── hello.py        # Python — /api/hello
│   └── service.go          # Go — /service
├── go.mod
├── cloud-functions/requirements.txt
└── package.json

注記: 各ファイルは、それぞれ独自のランタイムを持つ独立した関数としてビルドおよびデプロイされます。プラットフォームはファイル拡張子から言語を判別します。

コメント