jpskill.com
🛠️ 開発・MCP コミュニティ

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本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
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
🪟 Windows (PowerShell)
$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. 1. 下の青いボタンを押して hasura.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → hasura フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

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

  1. Permissions on every table — Tables without permissions are invisible to non-admin roles; define permissions as part of your schema
  2. Use relationships — Define foreign key relationships; Hasura auto-generates nested queries (no N+1 problem)
  3. Event triggers for side effects — Use event triggers (not polling) for email, notifications, and external API calls
  4. Actions for business logic — Complex operations (payments, multi-step workflows) go in Actions, not in client code
  5. Migrations in CI/CD — Export metadata and migrations; apply via CLI in your deployment pipeline
  6. Admin secret ≠ user auth — Use JWT or webhook auth for users; admin secret is for CI/CD and internal tools only
  7. Subscriptions for real-time — Use GraphQL subscriptions instead of polling; Hasura handles WebSocket efficiently
  8. Use views for complex queries — Create PostgreSQL views for complex aggregations; track them as tables in Hasura