Salta ai contenuti

Hasura Cheat Sheet

Overview

Hasura is a GraphQL engine that connects to your databases and microservices and instantly provides a production-ready GraphQL and REST API. It supports PostgreSQL, MySQL, SQL Server, BigQuery, and other data sources. Hasura auto-generates queries, mutations, and subscriptions based on your database schema, eliminating the need to write resolver code.

Hasura includes a role-based authorization system, event triggers for async business logic, scheduled triggers for cron jobs, remote schemas for federating other GraphQL services, and Actions for wrapping REST endpoints as GraphQL. It can be self-hosted via Docker or used as a managed cloud service.

Installation

Docker (Self-Hosted)

# Create a docker-compose.yml
cat > docker-compose.yml << 'EOF'
version: "3.6"
services:
  postgres:
    image: postgres:16
    restart: always
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword

  hasura:
    image: hasura/graphql-engine:v2.42.0
    ports:
      - "8080:8080"
    restart: always
    depends_on:
      - postgres
    environment:
      HASURA_GRAPHQL_METADATA_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
      HASURA_GRAPHQL_DEV_MODE: "true"
      HASURA_GRAPHQL_ADMIN_SECRET: myadminsecret

volumes:
  db_data:
EOF

# Start Hasura
docker compose up -d

# Open console at http://localhost:8080/console

Hasura CLI

# Install the CLI
curl -L https://github.com/hasura/graphql-engine/raw/stable/cli/get.sh | bash

# Or via npm
npm install -g hasura-cli

# Verify installation
hasura version

# Initialize a project
hasura init my-project --endpoint http://localhost:8080 --admin-secret myadminsecret
cd my-project

Core Commands

CLI Commands

CommandDescription
hasura initInitialize a new Hasura project
hasura consoleOpen the web console with migration tracking
hasura migrate createCreate a new migration
hasura migrate applyApply pending migrations
hasura migrate statusShow migration status
hasura metadata applyApply metadata to the server
hasura metadata exportExport metadata from the server
hasura seed createCreate a new seed file
hasura seed applyApply seed data
hasura deployApply migrations and metadata together

Migration Workflow

# Start console with migration tracking
hasura console --admin-secret myadminsecret

# Create a migration manually
hasura migrate create create_users_table --up-sql \
  "CREATE TABLE users (id serial PRIMARY KEY, name text, email text UNIQUE);" \
  --down-sql "DROP TABLE users;"

# Apply migrations
hasura migrate apply --admin-secret myadminsecret

# Check status
hasura migrate status --admin-secret myadminsecret

# Rollback last migration
hasura migrate apply --down 1 --admin-secret myadminsecret

# Squash migrations
hasura migrate squash --from 1234567890123 --name merged_migrations

GraphQL Operations

Queries

# Simple query
query {
  users {
    id
    name
    email
  }
}

# Query with filtering
query {
  users(where: { email: { _like: "%@example.com" } }) {
    id
    name
  }
}

# Query with pagination and sorting
query {
  users(limit: 10, offset: 20, order_by: { created_at: desc }) {
    id
    name
    created_at
  }
}

# Query with relationships
query {
  users {
    id
    name
    posts(order_by: { created_at: desc }, limit: 5) {
      title
      content
    }
  }
}

# Aggregations
query {
  users_aggregate {
    aggregate {
      count
      max { created_at }
    }
  }
}

Mutations

# Insert
mutation {
  insert_users_one(object: { name: "Alice", email: "alice@example.com" }) {
    id
    name
  }
}

# Bulk insert
mutation {
  insert_users(objects: [
    { name: "Bob", email: "bob@example.com" },
    { name: "Charlie", email: "charlie@example.com" }
  ]) {
    affected_rows
    returning { id name }
  }
}

# Update
mutation {
  update_users(where: { id: { _eq: 1 } }, _set: { name: "Alice Updated" }) {
    affected_rows
  }
}

# Delete
mutation {
  delete_users(where: { email: { _eq: "old@example.com" } }) {
    affected_rows
  }
}

# Upsert
mutation {
  insert_users_one(
    object: { name: "Alice", email: "alice@example.com" }
    on_conflict: { constraint: users_email_key, update_columns: [name] }
  ) {
    id
  }
}

Subscriptions

# Real-time subscription
subscription {
  messages(order_by: { created_at: desc }, limit: 10) {
    id
    content
    user { name }
    created_at
  }
}

Configuration

Environment Variables

# Core settings
HASURA_GRAPHQL_DATABASE_URL=postgres://user:pass@host:5432/db
HASURA_GRAPHQL_ADMIN_SECRET=your-admin-secret
HASURA_GRAPHQL_ENABLE_CONSOLE=true
HASURA_GRAPHQL_DEV_MODE=true

# Authentication
HASURA_GRAPHQL_JWT_SECRET='{"type":"RS256","jwk_url":"https://auth.example.com/.well-known/jwks.json"}'
HASURA_GRAPHQL_UNAUTHORIZED_ROLE=anonymous

# Performance
HASURA_GRAPHQL_CONNECTIONS_PER_READ_REPLICA=50
HASURA_GRAPHQL_LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL=1000
HASURA_GRAPHQL_STRINGIFY_NUMERIC_TYPES=true

# Logging
HASURA_GRAPHQL_LOG_LEVEL=info
HASURA_GRAPHQL_ENABLED_LOG_TYPES=startup,http-log,webhook-log,websocket-log,query-log

Permissions (Role-Based Access)

# metadata/databases/default/tables/public_users.yaml
- table:
    schema: public
    name: users
  select_permissions:
    - role: user
      permission:
        columns: [id, name, email, avatar_url]
        filter:
          id: { _eq: X-Hasura-User-Id }
  insert_permissions:
    - role: user
      permission:
        columns: [name, avatar_url]
        set:
          id: X-Hasura-User-Id
        check:
          id: { _eq: X-Hasura-User-Id }

Advanced Usage

Event Triggers

# Create an event trigger via CLI metadata
# metadata/databases/default/tables/public_orders.yaml
- table:
    schema: public
    name: orders
  event_triggers:
    - name: order_created
      definition:
        enable_manual: false
        insert:
          columns: "*"
      retry_conf:
        num_retries: 3
        interval_sec: 10
        timeout_sec: 60
      webhook: https://api.example.com/webhooks/order-created
      headers:
        - name: x-webhook-secret
          value_from_env: WEBHOOK_SECRET

Actions (Custom Business Logic)

# Define an Action
type Mutation {
  createUser(name: String!, email: String!): CreateUserOutput
}

type CreateUserOutput {
  id: Int!
  name: String!
  email: String!
}
# Handler endpoint receives:
# POST https://your-api.com/create-user
# { "action": { "name": "createUser" }, "input": { "name": "...", "email": "..." } }

Remote Schemas

# Add a remote GraphQL schema via metadata
hasura metadata apply
# Or add via console: Remote Schemas > Add

Troubleshooting

IssueSolution
Console not loadingCheck HASURA_GRAPHQL_ENABLE_CONSOLE is true; verify port mapping
Migration conflictsUse hasura migrate squash to consolidate; check schema_migrations table
Permission denied errorsVerify role permissions in metadata; check JWT claims include correct role
Slow queriesEnable query analysis in console; add database indexes for filtered columns
Subscription disconnectsCheck WebSocket connection limits; increase LIVE_QUERIES_MULTIPLEXED_REFETCH_INTERVAL
Metadata out of syncRun hasura metadata reload or hasura metadata apply
Docker OOMIncrease Docker memory limits; reduce connection pool size
JWT validation failingVerify HASURA_GRAPHQL_JWT_SECRET format; check token expiry and claims