https://hasura.io/docs/latest/_images/auth-high-level-overview1.png

前言

如果你希望为你的数据库获得一个开箱即用的 GraphQL 服务,其他工具可能更适合你的情况:Hasura, Postgraphile

Hasura GraphQL 引擎 能够根据数据库(数据表) 自动生成 GraphQL schema,并且处理 GraphQL 查询, 订阅 和 变更。

Schema 生成

我们只需要跟踪表或视图,并且创建他们之间的关联关系,Hasura 引擎将自动生成 GraphQL schema。

跟踪表时将自动生成如下内容:

  • 关于该表的 GraphQL 类型定义
  • 查询:支持 where(条件搜索)、oreder_by(排序)、limit 和 offset(分页)的查询
  • 订阅:支持 where(条件搜索)、oreder_by(排序)、limit 和 offset(分页)的订阅
  • 新增:支持冲突更新的单条新增;支持批量新增;
  • 更新:支持 where 条件的批量更新
  • 删除:支持 where 条件的批量删除
表/视图(Tables/Views)

跟踪表时将自动生成如下内容:

  • 定义:关于该表的 GraphQL 类型定义

  • 查询:支持 where(条件搜索)、oreder_by(排序)、limit 和 offset(分页)的查询

  • 订阅:支持 where(条件搜索)、oreder_by(排序)、limit 和 offset(分页)的订阅

  • 新增:支持冲突更新的单条新增;支持批量新增;

  • 更新:支持 where 条件的批量更新

  • 删除:支持 where 条件的批量删除

  • 视图不支持变更,因此只具有表的前 3 条功能
关系(Relationships)

当在 Hasura 引擎中创建表/视图与其他表/视图关系后,引擎自动完成下述内容:

  • 在表/视图中增加对象类型的字段,方便通过嵌套的方式查询数据
  • 为嵌套对象增加 where 和 order_by 语法,便于过滤和排序
解析器(Resolvers)

Hasura 不需要任何手写任何解析器,它自身就是一个编译器,能够将 GraphQL 查询编译成高效的 SQL 查询语句。

Hasura 针对 SQL 查询做了优化,能够充分利用 SQL 的功能,实现高效的查询。

元数据(Metadata)

Hasura 将 schema 生成所需要的全部信息 以元数据的方式存储 在“目录”中,它实际上是元数据数据库中的一个特殊 Postgres schema。

元数据目录

元数据目录是 Hasura 系统内部的表,被用于管理数据库状态和 GraphQL schema。

Hasura 引擎使用元数据生成能够被不同客户端访问的 GraphQL API。

Hasura 引擎将元数据存储在 Postgres 元数据库中,默认和业务数据所在位置相同。

初始化的时候,Hasura 在元数据库中创建一个叫做hdb_catalog的 schema,并且初始化一些表,详情见下文。

hdb_catalog schema

Hasura 创建它的目的是为了管理系统内部的状态。

当使用 Hasura 面板或 API 创建或更新表/权限/关系时,Hasura 将捕获该信息,同时将信息存储到相应的表中。

下面的表是 Hasura 用到的:

hdb_table table

hdb_table存储所有表/视图被创建或追踪的相关信息.

hdb_table

  • table_schema:
  • table_name:
  • is_system_defined:真代表由系统内部创建;假代表由用户创建
hdb_relationship table

hdb_relationship存储表/视图间的关联信息。

hdb_relationship

  • table_schema:
  • table_name:
  • rel_name:关系的名称
  • rel_type:权限类型(insert/select/update/delete)
  • perm_def:关系定义的相关信息
{
  "foreign_key_constraint_on": "user_id"
}
  • comment:关系的备注
  • is_system_defined:真代表由系统内部创建;假代表由用户创建
hdb_permission table

hdb_permission存储与表或视图权限控制规则相关的信息。

  • table_schema:
  • table_name:
  • role_name:使用该权限的角色名称
  • perm_type:权限类型(insert/select/update/delete)
  • perm_def:权限定义的相关信息

当一个请求携带上述角色访问上述表时,引擎将先验证被用户请求的字段是否有访问权限。只要请求通过验证,这个 filter字段定义的过滤器将返回适当的结果。例如:

{
  "columns": ["id", "name"],
  "filter": {
    "id": {
      "_eq": "X-HASURA-USER-ID"
    }
  }
}
  • comment:权限的备注
  • is_system_defined:真代表由系统内部创建;假代表由用户创建

注意:上述内容将持续更新。截止到上一次更新,后续可能有新的表或字段增加到目录中,以便于支持新的特性。

Exploring the catalogue

通过 Postgres 客户端访问 hdb_catalog schema,你可以核查当前 schema 和目录内容。

Catalogue versioning

当目录的 schema 被修改后,系统将自动升级目录版本。

如果有 Hasura 引擎更新期间有新的版本可用,目录版本也将在系统启动时更新。

参考

https://hasura.io/docs/latest/_images/auth-webhook-overview1.png

https://hasura.io/learn/zh/graphql/hasura/what-next/

https://www.graphqlweekly.com/

N+1 问题讨论:https://stackoverflow.com/questions/97197/what-is-the-n1-selects-problem-in-orm-object-relational-mapping