Hasura 教程

1. 什么是 Hasura?

Hasura 是一个开源的 GraphQL API 引擎,它可以自动为 PostgreSQL 数据库生成 GraphQL API。Hasura 提供了实时数据同步、认证、授权、事件触发器等功能,使开发者能够快速构建和部署 GraphQL API。

2. Hasura 的核心概念

2.1 项目 (Project)

项目是 Hasura 资源的组织单元,每个 Hasura 实例都包含一个或多个项目。

2.2 数据库 (Database)

Hasura 使用 PostgreSQL 作为底层数据库,支持连接多个数据库。

2.3 模式 (Schema)

模式是数据库结构的定义,包括表、列、关系等。

2.4 权限 (Permissions)

权限定义了谁可以访问和修改数据库中的数据。

2.5 角色 (Roles)

角色是权限的集合,用户可以被分配到一个或多个角色。

2.6 事件触发器 (Event Triggers)

事件触发器允许在数据库事件(如插入、更新、删除)发生时执行自定义逻辑。

2.7 远程模式 (Remote Schemas)

远程模式允许 Hasura 连接到其他 GraphQL API,将它们合并到一个统一的 API 中。

2.8 操作 (Actions)

操作允许 Hasura 执行自定义 GraphQL 解析器,调用 REST API 或其他服务。

2.9 实时 (Realtime)

实时功能允许数据在客户端之间实时同步,基于 GraphQL subscriptions。

3. Hasura 的安装和配置

3.1 安装 Hasura

Hasura 可以通过多种方式安装:

3.1.1 使用 Docker

# 创建 docker-compose.yml 文件
version: '3.6'
services:
  postgres:
    image: postgres:13
    restart: always
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgrespassword
  graphql-engine:
    image: hasura/graphql-engine:v2.0.0
    ports:
      - "8080:8080"
    depends_on:
      - postgres
    restart: always
    environment:
      HASURA_GRAPHQL_DATABASE_URL: postgres://postgres:postgrespassword@postgres:5432/postgres
      HASURA_GRAPHQL_ENABLE_CONSOLE: "true"
      HASURA_GRAPHQL_ADMIN_SECRET: myadminsecretkey
volumes:
  db_data:

# 启动服务
docker-compose up -d

3.1.2 使用 Hasura Cloud

  1. 访问 Hasura Cloud
  2. 注册并登录
  3. 点击 "Create Project"
  4. 输入项目名称并选择区域
  5. 点击 "Create"

3.2 访问 Hasura 控制台

  • Docker 安装:访问 http://localhost:8080
  • Hasura Cloud:访问控制台 URL(在 Hasura Cloud 项目详情页中获取)

3.3 连接数据库

  1. 在 Hasura 控制台中,导航到 "Data" 部分
  2. 点击 "Connect Database"
  3. 输入数据库连接信息
  4. 点击 "Connect"

4. Hasura 的基本使用

4.1 创建表

  1. 在 Hasura 控制台中,导航到 "Data" 部分
  2. 选择一个数据库
  3. 点击 "Create Table"
  4. 输入表名、列定义和约束
  5. 点击 "Add Table"

4.2 定义关系

  1. 在 Hasura 控制台中,导航到 "Data" 部分
  2. 选择一个表
  3. 点击 "Relationships" 选项卡
  4. 点击 "Add Relationship"
  5. 定义关系名称、目标表和外键
  6. 点击 "Save"

4.3 设置权限

  1. 在 Hasura 控制台中,导航到 "Data" 部分
  2. 选择一个表
  3. 点击 "Permissions" 选项卡
  4. 选择一个角色
  5. 定义 SELECT、INSERT、UPDATE、DELETE 权限
  6. 点击 "Save Permissions"

4.4 使用 GraphQL API

Hasura 自动为数据库生成 GraphQL API,你可以通过以下方式使用:

4.4.1 查询数据

query GetUsers {
  users {
    id
    name
    email
    posts {
      id
      title
      content
    }
  }
}

4.4.2 插入数据

mutation InsertUser {
  insert_users(objects: { name: "John Doe", email: "john@example.com" }) {
    returning {
      id
      name
      email
    }
  }
}

4.4.3 更新数据

mutation UpdateUser {
  update_users(where: { id: { _eq: 1 } }, _set: { name: "John Smith" }) {
    returning {
      id
      name
      email
    }
  }
}

4.4.4 删除数据

mutation DeleteUser {
  delete_users(where: { id: { _eq: 1 } }) {
    returning {
      id
      name
      email
    }
  }
}

4.4.5 实时订阅

subscription GetUsers {
  users {
    id
    name
    email
  }
}

5. Hasura 的高级功能

5.1 使用事件触发器

事件触发器允许在数据库事件发生时执行自定义逻辑:

  1. 在 Hasura 控制台中,导航到 "Events" 部分
  2. 点击 "Create Event Trigger"
  3. 输入触发器名称、表名和事件类型
  4. 输入 Webhook URL
  5. 点击 "Create"

5.2 使用远程模式

远程模式允许 Hasura 连接到其他 GraphQL API:

  1. 在 Hasura 控制台中,导航到 "Remote Schemas" 部分
  2. 点击 "Add Remote Schema"
  3. 输入模式名称和 GraphQL API URL
  4. 点击 "Add"

5.3 使用操作

操作允许 Hasura 执行自定义 GraphQL 解析器:

  1. 在 Hasura 控制台中,导航到 "Actions" 部分
  2. 点击 "Create Action"
  3. 输入操作名称、GraphQL 类型定义和 Webhook URL
  4. 点击 "Create"

5.4 使用认证

Hasura 支持多种认证方式:

5.4.1 JWT 认证

  1. 配置 JWT 密钥:
# 在 docker-compose.yml 中添加环境变量
HASURA_GRAPHQL_JWT_SECRET: '{"type":"RS256","key":"<your-jwt-secret>"}'
  1. 客户端发送 JWT 令牌:
const { GraphQLClient } = require('graphql-request');

const client = new GraphQLClient('http://localhost:8080/v1/graphql', {
  headers: {
    'Authorization': 'Bearer <your-jwt-token>'
  }
});

5.4.2 Webhook 认证

  1. 配置 Webhook URL:
# 在 docker-compose.yml 中添加环境变量
HASURA_GRAPHQL_AUTH_HOOK: 'http://localhost:3000/auth'
  1. 实现认证 Webhook:
// auth.js
const express = require('express');
const app = express();
app.use(express.json());

app.post('/auth', (req, res) => {
  const { authorization } = req.headers;
  // 验证令牌
  if (authorization === 'Bearer valid-token') {
    res.json({
      'X-Hasura-Role': 'user',
      'X-Hasura-User-ID': '1'
    });
  } else {
    res.status(401).json({ error: 'Unauthorized' });
  }
});

app.listen(3000);

5.5 使用实时功能

Hasura 支持 GraphQL subscriptions,实现实时数据同步:

import { gql, useSubscription } from '@apollo/client';

const GET_USERS = gql`
  subscription GetUsers {
    users {
      id
      name
      email
    }
  }
`;

function UsersList() {
  const { data, loading } = useSubscription(GET_USERS);
  
  if (loading) return <p>Loading...</p>;
  
  return (
    <ul>
      {data.users.map(user => (
        <li key={user.id}>{user.name} - {user.email}</li>
      ))}
    </ul>
  );
}

6. Hasura 的最佳实践

6.1 安全最佳实践

  • 使用角色和权限:为所有表设置适当的权限
  • 使用 JWT 或 Webhook 认证:实现安全的用户认证
  • 验证用户输入:在客户端和服务器端验证用户输入
  • 使用 HTTPS:确保所有通信都使用 HTTPS

6.2 性能最佳实践

  • 使用索引:为常用查询创建适当的索引
  • 优化查询:使用适当的查询条件和选择必要的字段
  • 使用缓存:缓存频繁访问的数据
  • 限制订阅:只订阅必要的数据变化

6.3 架构最佳实践

  • 使用远程模式:将不同的业务逻辑分离到不同的服务中
  • 使用操作:处理复杂的业务逻辑
  • 使用事件触发器:处理异步任务
  • 使用数据库视图:创建数据库视图以简化查询

6.4 部署最佳实践

  • 使用 Hasura Cloud:对于生产环境,使用 Hasura Cloud 获得更好的可靠性和性能
  • 配置监控:监控 Hasura 实例的性能和错误
  • 设置备份:定期备份数据库
  • 使用环境变量:使用环境变量存储敏感信息

7. 实际应用示例

7.1 构建一个博客 API

  1. 创建表

    • users 表:存储用户信息
    • posts 表:存储博客文章
    • comments 表:存储评论
  2. 定义关系

    • usersposts:一对多
    • postscomments:一对多
    • userscomments:一对多
  3. 设置权限

    • anonymous 角色:可以查看帖子和评论
    • user 角色:可以查看、创建、更新自己的帖子和评论
    • admin 角色:可以查看、创建、更新、删除所有内容
  4. 使用 GraphQL API

# 查询帖子和评论
query GetPosts {
  posts {
    id
    title
    content
    author {
      id
      name
    }
    comments {
      id
      content
      author {
        id
        name
      }
    }
  }
}

# 创建帖子
mutation CreatePost {
  insert_posts(objects: { title: "Hello World", content: "First post", user_id: 1 }) {
    returning {
      id
      title
      content
    }
  }
}

# 创建评论
mutation CreateComment {
  insert_comments(objects: { content: "Great post!", post_id: 1, user_id: 1 }) {
    returning {
      id
      content
    }
  }
}

7.2 构建一个电商 API

  1. 创建表

    • users 表:存储用户信息
    • products 表:存储产品信息
    • orders 表:存储订单信息
    • order_items 表:存储订单项目
  2. 定义关系

    • usersorders:一对多
    • ordersorder_items:一对多
    • productsorder_items:一对多
  3. 设置权限

    • anonymous 角色:可以查看产品
    • user 角色:可以查看产品,创建订单,查看自己的订单
    • admin 角色:可以查看、创建、更新、删除所有内容
  4. 使用 GraphQL API

# 查询产品
query GetProducts {
  products {
    id
    name
    price
    description
  }
}

# 创建订单
mutation CreateOrder {
  insert_orders(objects: { user_id: 1, total: 99.99 }) {
    returning {
      id
      total
      created_at
    }
  }
}

# 创建订单项目
mutation CreateOrderItem {
  insert_order_items(objects: { order_id: 1, product_id: 1, quantity: 1, price: 99.99 }) {
    returning {
      id
      quantity
      price
    }
  }
}

# 查询用户订单
query GetUserOrders {
  orders(where: { user_id: { _eq: 1 } }) {
    id
    total
    created_at
    order_items {
      id
      quantity
      price
      product {
        id
        name
      }
    }
  }
}

7.3 构建一个实时聊天 API

  1. 创建表

    • users 表:存储用户信息
    • rooms 表:存储聊天房间
    • messages 表:存储消息
  2. 定义关系

    • usersmessages:一对多
    • roomsmessages:一对多
  3. 设置权限

    • user 角色:可以查看房间,发送消息,查看房间中的消息
  4. 使用 GraphQL API

# 查询房间
query GetRooms {
  rooms {
    id
    name
  }
}

# 发送消息
mutation SendMessage {
  insert_messages(objects: { content: "Hello everyone!", user_id: 1, room_id: 1 }) {
    returning {
      id
      content
      created_at
      user {
        id
        name
      }
    }
  }
}

# 实时订阅消息
subscription GetMessages {
  messages(where: { room_id: { _eq: 1 } }, order_by: { created_at: asc }) {
    id
    content
    created_at
    user {
      id
      name
    }
  }
}

8. Hasura 与其他 API 解决方案的比较

8.1 Hasura vs REST API

  • 开发速度:Hasura 自动生成 API,开发速度更快
  • 灵活性:GraphQL 允许客户端选择需要的字段,更灵活
  • 性能:GraphQL 减少了过度获取和不足获取的问题
  • 维护:Hasura 减少了 API 维护成本

8.2 Hasura vs 自定义 GraphQL API

  • 开发速度:Hasura 自动生成 API,开发速度更快
  • 复杂性:Hasura 减少了构建和维护 GraphQL API 的复杂性
  • 功能:Hasura 提供了实时数据、认证、授权等开箱即用的功能
  • 扩展性:两者都可以扩展,但 Hasura 提供了更简单的扩展方式

8.3 Hasura vs Supabase

  • 功能:两者都提供了类似的功能,但 Hasura 更专注于 GraphQL API
  • 数据库支持:Hasura 支持多个数据库,而 Supabase 主要支持 PostgreSQL
  • 扩展性:Hasura 提供了更多的扩展选项,如远程模式和操作
  • 生态系统:Supabase 提供了更完整的 BaaS 功能,如存储和函数

9. 总结

Hasura 是一个强大的开源 GraphQL API 引擎,它可以自动为 PostgreSQL 数据库生成 GraphQL API。Hasura 提供了实时数据同步、认证、授权、事件触发器等功能,使开发者能够快速构建和部署 GraphQL API。

Hasura 的主要优势包括:

  • 快速开发:自动生成 GraphQL API,减少开发时间
  • 实时数据:支持 GraphQL subscriptions,实现实时数据同步
  • 强大的权限系统:细粒度的权限控制
  • 可扩展性:支持远程模式、操作和事件触发器
  • 易于使用:提供了直观的控制台界面

通过遵循最佳实践,你可以构建安全、高性能、可靠的 Hasura API。无论是构建博客、电商还是聊天应用,Hasura 都能为你提供强大的支持。

« 上一篇 Supabase 教程 下一篇 » Apollo Server 中文教程