frappe-api-development について
Frappe 開発者向けの API 開発スキルです。REST、RPC、Webhook の方式に加え、認証、権限、入力検証を扱い、外部連携やフロントエンドへの業務ロジック公開に役立ちます。
主な機能
- 01REST、RPC、Webhook 方式の選択
- 02カスタム RPC エンドポイントの作成
- 03トークンやセッション認証の設定
- 04権限確認と入力検証
- 05長時間処理のバックグラウンド実行
活用シーン
- 01DocType の CRUD エンドポイント提供
- 02フロントエンドへの独自業務操作の公開
- 03外部システムからのコールバック受信
- 04長時間のエクスポート実行と状態確認
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ lubusin/ frappe-skills --skill frappe-api-developmentインストール後、Claude Code で/frappe-api-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/authentication.mdoauth.mdpermissions.mdpython-api.mdrate-limiting.mdrest-api.mdserver-scripts.mdwebhooks.md詳細
Frappe API 開発
Frappe の REST および RPC パターンを使用して、安全で適切に設計された API を構築します。
使用する場面
- カスタム RPC エンドポイント(
@frappe.whitelist)の作成 - REST API 連携の構築
- 外部システム向けの Webhook の実装
- API 認証(トークン、OAuth)の設定
- フロントエンドへのビジネスロジックの公開
必要な入力
- API の目的(CRUD、アクション、連携)
- 認証要件(公開、ユーザー、API キー)
- エンドポイントごとの権限要件
- リクエスト/レスポンス形式の要件
手順
0) API パターンを選択する
| 必要な処理 | パターン |
|---|---|
| DocType の CRUD | 組み込みの REST API を使用 |
| カスタムアクション | @frappe.whitelist を使用した RPC |
| 外部からのコールバック | Webhook DocType |
| バッチ処理 | バックグラウンドジョブ+ステータスエンドポイント |
1) 組み込みの REST API(DocType の CRUD)
Frappe は、すべての DocType に対して自動的に REST エンドポイントを提供します。
# Create
POST /api/resource/Customer
{"customer_name": "Acme Corp"}
# Read
GET /api/resource/Customer/CUST-001
# Update
PUT /api/resource/Customer/CUST-001
{"customer_name": "Acme Corporation"}
# Delete
DELETE /api/resource/Customer/CUST-001
# List with filters
GET /api/resource/Customer?filters=[["status","=","Active"]]
2) カスタム RPC エンドポイント
アプリ内にホワイトリスト登録したメソッドを作成します。
# my_app/api.py
import frappe
@frappe.whitelist()
def process_order(order_id, action):
"""Process an order with the given action."""
# Always verify permissions
doc = frappe.get_doc("Sales Order", order_id)
if not frappe.has_permission("Sales Order", "write", doc):
frappe.throw("Not permitted", frappe.PermissionError)
# Business logic
if action == "approve":
doc.status = "Approved"
doc.save()
return {"status": "success", "order": doc.name}
@frappe.whitelist(allow_guest=True)
def public_endpoint():
"""Public endpoint - no auth required."""
return {"message": "Hello, World!"}
次の方法で呼び出します。
POST /api/method/my_app.api.process_order
{"order_id": "SO-001", "action": "approve"}
3) 認証を実装する
API キー+シークレット(連携に推奨):
# Header format
Authorization: token api_key:api_secret
ベアラートークン:
Authorization: Bearer <token>
セッション(ログイン済みユーザー向け): Cookie により自動的に認証されます。
4) 権限チェック
RPC メソッドでは必ず権限をチェックしてください。
@frappe.whitelist()
def sensitive_action(docname):
doc = frappe.get_doc("My DocType", docname)
# Check document-level permission
if not frappe.has_permission("My DocType", "write", doc):
frappe.throw("Not permitted", frappe.PermissionError)
# Check role-based permission
if "Manager" not in frappe.get_roles():
frappe.throw("Manager role required")
# Proceed with action
...
5) 入力の検証
@frappe.whitelist()
def create_item(name, qty, price):
# Validate required fields
if not name:
frappe.throw("Name is required")
# Validate types
qty = frappe.utils.cint(qty)
price = frappe.utils.flt(price)
# Validate ranges
if qty <= 0:
frappe.throw("Quantity must be positive")
# Proceed
...
6) レスポンス形式
成功レスポンス:
return {
"status": "success",
"data": {...}
}
エラー処理:
# User-facing error
frappe.throw("Validation failed", title="Error")
# Permission error
frappe.throw("Not allowed", frappe.PermissionError)
# Standard exceptions become {"exc_type": "...", "exc": "..."}
7) 時間のかかる処理にはバックグラウンドジョブを使用する
@frappe.whitelist()
def start_export(filters):
job = frappe.enqueue(
"my_app.jobs.run_export",
filters=filters,
queue="long",
timeout=600
)
return {"job_id": job.id}
@frappe.whitelist()
def check_job_status(job_id):
from frappe.utils.background_jobs import get_job
job = get_job(job_id)
return {"status": job.get_status()}
検証
- 有効なリクエストに対してエンドポイントが正しく応答する
- 権限のないアクセスに対して権限エラーが返される
- 入力検証で無効なデータが拒否される
- エラーレスポンスが構造化され、役立つ内容になっている
- 実行する:
bench --site <site> console→ エンドポイントを手動でテストする
問題発生時の対処/デバッグ
- メソッドが見つからない:URL 内のモジュールパスが Python のパスと一致しているか確認します
- 権限が拒否される:
@frappe.whitelist()デコレーターとユーザー権限を確認します - CSRF エラー:API 呼び出しに適切な認証ヘッダーを使用します
- 500 エラー:エラーログを確認します:
bench --site <site> show-log
エスカレーション
- OAuth 連携については、references/oauth.md を参照してください
- Webhook パターンについては、references/webhooks.md を参照してください
- レート制限については、references/rate-limiting.md を参照してください
参考資料
- references/rest-api.md - REST API の詳細
- references/authentication.md - 認証パターン
- references/permissions.md - 権限システム
- references/webhooks.md - アウトバウンド Webhook
ガードレール
- 入力を必ず検証する:クライアントのデータを決して信用せず、サーバー側で型、長さ、形式を検証します
- 権限コールバックを使用する:ホワイトリスト登録したメソッド内で
frappe.has_permission()を明示的に確認します - ユーザー入力をサニタイズする:SQL には
frappe.db.escape()を使用し、eval()や動的コード実行は避けます - レート制限を処理する:不正利用を防ぐため、公開 API にレート制限を実装します
- 構造化されたエラーを返す:適切な HTTP ステータスコードとともに
frappe.throw()を使用します
よくある間違い
| 間違い | 発生する問題 | 修正方法 |
|---|---|---|
@frappe.whitelist() がない | メソッドが「Method not found」エラーを返す | API 経由でメソッドを公開するため、デコレーターを追加する |
| 更新処理に GET を使用する | REST の慣例に反し、CSRF の問題が発生する | データの変更には POST/PUT/DELETE を使用する |
| エラーを処理しない | 500 エラーでスタックトレースが露出する | try/except で囲み、frappe.throw() を使用する |
| 機密データを公開する | セキュリティ侵害が発生する | レスポンスのフィールドを絞り込み、権限を確認する |
allow_guest=True がない | 公開エンドポイントが 403 を返す | 認証なしのアクセスを許可するには @frappe.whitelist(allow_guest=True) を追加する |
| クエリで SQL インジェクションが発生する | データベースが侵害される | Query Builder または frappe.db.escape() を使用する |
コメント
Markdown 対応