hasura
PostgreSQLなどのデータベース上に、リアルタイムなGraphQL APIを構築できるHasuraの導入、権限設定、ビジネスロジック記述、GraphQLクエリ最適化などを開発者がスムーズに行えるように支援するSkill。
📜 元の英語説明(参考)
Expert guidance for Hasura, the GraphQL engine that gives the agent instant, real-time GraphQL APIs over PostgreSQL (and other databases). Helps developers set up Hasura, configure permissions, write custom business logic with Actions and Event Triggers, and optimize GraphQL queries for production.
🇯🇵 日本人クリエイター向け解説
PostgreSQLなどのデータベース上に、リアルタイムなGraphQL APIを構築できるHasuraの導入、権限設定、ビジネスロジック記述、GraphQLクエリ最適化などを開発者がスムーズに行えるように支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o hasura.zip https://jpskill.com/download/14974.zip && unzip -o hasura.zip && rm hasura.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/14974.zip -OutFile "$d\hasura.zip"; Expand-Archive "$d\hasura.zip" -DestinationPath $d -Force; ri "$d\hasura.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
hasura.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
hasuraフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
Hasura — PostgreSQL 上のインスタント GraphQL API
概要
Hasura は、PostgreSQL (およびその他のデータベース) 上でインスタントかつリアルタイムな GraphQL API を提供する GraphQL エンジンです。開発者が Hasura のセットアップ、権限の設定、Actions および Event Triggers によるカスタムビジネスロジックの記述、本番環境向けの GraphQL クエリの最適化を行うのに役立ちます。
手順
クイックスタート
# ローカル開発用の Docker Compose
cat > docker-compose.yml << 'EOF'
version: "3.6"
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: postgrespassword
volumes:
- pgdata:/var/lib/postgresql/data
hasura:
image: hasura/graphql-engine:v2.42.0
ports:
- "8080:8080"
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
HASURA_GRAPHQL_ADMIN_SECRET: mysecretkey
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup,http-log,query-log
depends_on:
- postgres
volumes:
pgdata:
EOF
docker compose up -d
# コンソールは http://localhost:8080/console でアクセスできます
自動生成された API
# PostgreSQL で "users" テーブルを作成すると、
# Hasura はこれらの操作を自動生成します:
# フィルタリング、ソート、ページネーションによるすべてのユーザーのクエリ
query {
users(
where: { plan: { _eq: "pro" }, created_at: { _gte: "2026-01-01" } }
order_by: { created_at: desc }
limit: 20
offset: 0
) {
id
email
plan
created_at
# ネストされたリレーションシップ (外部キーから自動検出)
posts(where: { published: { _eq: true } }) {
id
title
}
posts_aggregate {
aggregate { count }
}
}
# 集計
users_aggregate(where: { plan: { _eq: "pro" } }) {
aggregate {
count
avg { lifetime_value }
}
}
}
# 挿入
mutation {
insert_users_one(object: {
email: "new@example.com"
plan: "free"
}) {
id
}
}
# 更新
mutation {
update_users(
where: { id: { _eq: "user-123" } }
_set: { plan: "pro" }
) {
affected_rows
returning { id plan }
}
}
# リアルタイムサブスクリプション
subscription {
users(where: { online: { _eq: true } }) {
id
email
last_seen
}
}
権限 (行レベルセキュリティ)
# metadata/databases/default/tables/public_orders.yaml
# ロールごとのきめ細かい権限
table:
name: orders
schema: public
# Select: ユーザーは自分の注文のみを表示できます
select_permissions:
- role: user
permission:
columns: [id, amount, status, created_at]
filter:
user_id: { _eq: X-Hasura-User-Id }
limit: 100
# Admin ロール: すべての注文を表示できます
- role: admin
permission:
columns: "*"
filter: {}
allow_aggregations: true
# Insert: ユーザーは自分の注文を作成できます
insert_permissions:
- role: user
permission:
columns: [amount, items, shipping_address]
set:
user_id: X-Hasura-User-Id # 認証トークンから自動設定
status: pending # 初期ステータスを強制
check:
amount: { _gt: 0 } # 検証: 正の金額
# Update: ユーザーは自分の保留中の注文のみをキャンセルできます
update_permissions:
- role: user
permission:
columns: [status]
filter:
user_id: { _eq: X-Hasura-User-Id }
status: { _eq: "pending" }
set: {}
check:
status: { _eq: "cancelled" } # キャンセルのみに設定可能
Actions (カスタムビジネスロジック)
# metadata/actions.yaml — カスタムリゾルバーで GraphQL を拡張
actions:
- name: processPayment
definition:
kind: synchronous
handler: http://api:3000/actions/process-payment
type: mutation
arguments:
- name: order_id
type: uuid!
- name: payment_method
type: String!
output_type: PaymentResult
permissions:
- role: user
// api/actions/process-payment.ts — Action ハンドラー
export default async function handler(req: Request) {
const { input, session_variables } = await req.json();
const userId = session_variables["x-hasura-user-id"];
const { order_id, payment_method } = input;
// 注文がユーザーに属しているか検証
const order = await db.query("SELECT * FROM orders WHERE id = $1 AND user_id = $2", [order_id, userId]);
if (!order.rows[0]) return Response.json({ error: "Not found" }, { status: 404 });
// Stripe 経由で支払い処理
const charge = await stripe.charges.create({
amount: order.rows[0].amount,
currency: "usd",
source: payment_method,
});
// 注文ステータスの更新
await db.query("UPDATE orders SET status = 'paid', payment_id = $1 WHERE id = $2", [charge.id, order_id]);
return Response.json({ success: true, payment_id: charge.id });
}
Event Triggers
# metadata/databases/default/tables/public_orders.yaml
event_triggers:
- name: on_order_paid
definition:
enable_manual: false
insert:
columns: "*"
update:
columns: [status]
retry_conf:
num_retries: 3
interval_sec: 10
webhook: http://api:3000/webhooks/order-paid
headers:
- name: x-webhook-secret
value_from_env: WEBHOOK_SECRET
// api/webhooks/order-paid.ts — Event trigger ハンドラー
export default async function handler(req: Request) {
const { event } = await req.json();
const { old: oldRow, new: newRow } = event.data;
// ステータスが "paid" に変更された場合のみ処理
if (newRow.status === "paid" && oldRow?.status !== "paid") {
// 確認メールを送信
await sendEmail(newRow.user_id, "Order Confirmed", `Order #${newRow.id} paid.`);
// 在庫を更新
await decrementInventory(newRow.items);
// フルフィルメントに通知
await notifyFulfillment(newRow);
}
return Response.json({ success: true });
}
Migrations
# コードからメタデータとマイグレーションを適用
hasura metadata apply
hasura migrate apply --database-name default 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Hasura — Instant GraphQL API on PostgreSQL
Overview
Hasura, the GraphQL engine that gives the user instant, real-time GraphQL APIs over PostgreSQL (and other databases). Helps developers set up Hasura, configure permissions, write custom business logic with Actions and Event Triggers, and optimize GraphQL queries for production.
Instructions
Quick Start
# Docker Compose for local development
cat > docker-compose.yml << 'EOF'
version: "3.6"
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: postgrespassword
volumes:
- pgdata:/var/lib/postgresql/data
hasura:
image: hasura/graphql-engine:v2.42.0
ports:
- "8080:8080"
environment:
HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
HASURA_GRAPHQL_ADMIN_SECRET: mysecretkey
HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
HASURA_GRAPHQL_DEV_MODE: "true"
HASURA_GRAPHQL_ENABLED_LOG_TYPES: startup,http-log,query-log
depends_on:
- postgres
volumes:
pgdata:
EOF
docker compose up -d
# Console at http://localhost:8080/console
Auto-Generated API
# After creating a "users" table in PostgreSQL,
# Hasura auto-generates these operations:
# Query all users with filtering, sorting, pagination
query {
users(
where: { plan: { _eq: "pro" }, created_at: { _gte: "2026-01-01" } }
order_by: { created_at: desc }
limit: 20
offset: 0
) {
id
email
plan
created_at
# Nested relationship (auto-detected from foreign keys)
posts(where: { published: { _eq: true } }) {
id
title
}
posts_aggregate {
aggregate { count }
}
}
# Aggregation
users_aggregate(where: { plan: { _eq: "pro" } }) {
aggregate {
count
avg { lifetime_value }
}
}
}
# Insert
mutation {
insert_users_one(object: {
email: "new@example.com"
plan: "free"
}) {
id
}
}
# Update
mutation {
update_users(
where: { id: { _eq: "user-123" } }
_set: { plan: "pro" }
) {
affected_rows
returning { id plan }
}
}
# Real-time subscription
subscription {
users(where: { online: { _eq: true } }) {
id
email
last_seen
}
}
Permissions (Row-Level Security)
# metadata/databases/default/tables/public_orders.yaml
# Fine-grained permissions per role
table:
name: orders
schema: public
# Select: users can only see their own orders
select_permissions:
- role: user
permission:
columns: [id, amount, status, created_at]
filter:
user_id: { _eq: X-Hasura-User-Id }
limit: 100
# Admin role: see all orders
- role: admin
permission:
columns: "*"
filter: {}
allow_aggregations: true
# Insert: users can create orders for themselves
insert_permissions:
- role: user
permission:
columns: [amount, items, shipping_address]
set:
user_id: X-Hasura-User-Id # Auto-set from auth token
status: pending # Force initial status
check:
amount: { _gt: 0 } # Validate: positive amount
# Update: users can only cancel their pending orders
update_permissions:
- role: user
permission:
columns: [status]
filter:
user_id: { _eq: X-Hasura-User-Id }
status: { _eq: "pending" }
set: {}
check:
status: { _eq: "cancelled" } # Can only set to cancelled
Actions (Custom Business Logic)
# metadata/actions.yaml — Extend GraphQL with custom resolvers
actions:
- name: processPayment
definition:
kind: synchronous
handler: http://api:3000/actions/process-payment
type: mutation
arguments:
- name: order_id
type: uuid!
- name: payment_method
type: String!
output_type: PaymentResult
permissions:
- role: user
// api/actions/process-payment.ts — Action handler
export default async function handler(req: Request) {
const { input, session_variables } = await req.json();
const userId = session_variables["x-hasura-user-id"];
const { order_id, payment_method } = input;
// Verify order belongs to user
const order = await db.query("SELECT * FROM orders WHERE id = $1 AND user_id = $2", [order_id, userId]);
if (!order.rows[0]) return Response.json({ error: "Not found" }, { status: 404 });
// Process payment via Stripe
const charge = await stripe.charges.create({
amount: order.rows[0].amount,
currency: "usd",
source: payment_method,
});
// Update order status
await db.query("UPDATE orders SET status = 'paid', payment_id = $1 WHERE id = $2", [charge.id, order_id]);
return Response.json({ success: true, payment_id: charge.id });
}
Event Triggers
# metadata/databases/default/tables/public_orders.yaml
event_triggers:
- name: on_order_paid
definition:
enable_manual: false
insert:
columns: "*"
update:
columns: [status]
retry_conf:
num_retries: 3
interval_sec: 10
webhook: http://api:3000/webhooks/order-paid
headers:
- name: x-webhook-secret
value_from_env: WEBHOOK_SECRET
// api/webhooks/order-paid.ts — Event trigger handler
export default async function handler(req: Request) {
const { event } = await req.json();
const { old: oldRow, new: newRow } = event.data;
// Only process when status changes to "paid"
if (newRow.status === "paid" && oldRow?.status !== "paid") {
// Send confirmation email
await sendEmail(newRow.user_id, "Order Confirmed", `Order #${newRow.id} paid.`);
// Update inventory
await decrementInventory(newRow.items);
// Notify fulfillment
await notifyFulfillment(newRow);
}
return Response.json({ success: true });
}
Migrations
# Apply metadata and migrations from code
hasura metadata apply
hasura migrate apply --database-name default
# Create a new migration
hasura migrate create add_orders_table --database-name default
# Export current state
hasura metadata export
hasura migrate create init --from-server --database-name default
Installation
# CLI
npm install -g hasura-cli
# Docker
docker pull hasura/graphql-engine:latest
# Hasura Cloud (managed)
# https://cloud.hasura.io
Examples
Example 1: Building a feature with Hasura
User request:
Add a real-time collaborative quick start to my React app using Hasura.
The agent installs the package, creates the component with proper Hasura initialization, implements the quick start with event handling and state management, and adds TypeScript types for the integration.
Example 2: Migrating an existing feature to Hasura
User request:
I have a basic auto-generated api built with custom code. Migrate it to use Hasura for better auto-generated api support.
The agent reads the existing implementation, maps the custom logic to Hasura's API, rewrites the components using Hasura's primitives, preserves existing behavior, and adds features only possible with Hasura (like Permissions, Actions).
Guidelines
- Permissions on every table — Tables without permissions are invisible to non-admin roles; define permissions as part of your schema
- Use relationships — Define foreign key relationships; Hasura auto-generates nested queries (no N+1 problem)
- Event triggers for side effects — Use event triggers (not polling) for email, notifications, and external API calls
- Actions for business logic — Complex operations (payments, multi-step workflows) go in Actions, not in client code
- Migrations in CI/CD — Export metadata and migrations; apply via CLI in your deployment pipeline
- Admin secret ≠ user auth — Use JWT or webhook auth for users; admin secret is for CI/CD and internal tools only
- Subscriptions for real-time — Use GraphQL subscriptions instead of polling; Hasura handles WebSocket efficiently
- Use views for complex queries — Create PostgreSQL views for complex aggregations; track them as tables in Hasura