super-graph 核心代码说明

内容来自官方文档,主要介绍下super-graph 的工具原理,对于学习源码还是比较有帮助的

主要的子模块

  • qcode, 处理graphql 语言以及解析的
  • psql sql 生成器
  • serv http 服务,配置以及cli
  • rails rails cookies && session 存储解码器

组件说明

  • qcode
    主要处理grapql 的解析以及转换,通过func NewCompiler(c Config) 创建,注意qcode 不关心数据库结构
    核心是处理graphql 的解析
    核心代码:
 
const (
    opQuery
    opMutate
  ...
)
type QCode struct {
    Type      QType
  Selects   []Select
  ...
}
type Select struct {
    ID         int32
    ParentID   int32
    Args       map[string]*Node
    Name       string
    FieldName  string
    Cols       []Column
    Where      *Exp
    OrderBy    []*OrderBy
    DistinctOn []string
    Paging     Paging
    Children   []int32
    Functions  bool
    Allowed    map[string]struct{}
    PresetMap  map[string]string
    PresetList []string
}

但是在转换为qcode 之前,需要先进行词法解析(lex.go),生成item 类型,之后被parse.go 处理

type item struct {
    typ  itemType
    pos  Pos
    end  Pos
}

参考解析query getUser { user { id } }
生成的item

 
item{itemQuery, 0, 4} // query
item{itemName, 6, 12} // getUser
item{itemObjOpen, 16, 20} // {
...
 

之后通过parrs,解析出ast,格式

type Operation struct {
    Type    parserType
    Name    string
    Args    []Arg
    Fields  []Field
}
type Field struct {
    ID        int32
    ParentID  int32
    Name      string
    Alias     string
    Args      []Arg
    Children  []int32
}
  • psql
    主要目的是通过qcode 生成pg 的sql,psql 的入口为query.go
    核心代码,需要依赖tables.go (提供tabele 以及column的处理)
 
func NewCompiler(conf Config) *Compiler {
    return &Compiler{conf.Schema, conf.Vars}
}
func (co *Compiler) Compile(qc *qcode.QCode, w io.Writer, vars Variables) (uint32, error) {
    switch qc.Type {
    case qcode.QTQuery:
        return co.compileQuery(qc, w)
    case qcode.QTInsert, qcode.QTUpdate, qcode.QTDelete, qcode.QTUpsert:
        return co.compileMutation(qc, w, vars)
    }
    return 0, fmt.Errorf("Unknown operation type %d", qc.Type)
}

参考:

query {
  user {
    id
  }
  posts {
    title
  }
}

生成的sql(实际上还能处理更强大的rbac。。。)

SELECT users.id, posts.title FROM users, posts;
  • serv 包
    主要是处理http 服务的,同时也包含认证中间件,远程join 解析,配置解析,数据库迁移
    以及数据初始化处理,一个更强大的allow.list 进行一些query以及mutation 的处理(hasura也有类似的)
    当前支持的全局变量,后期会有变动
 
var (
    logger   zerolog.Logger  // logger for everything but errors
    errlog   zerolog.Logger  // logger for errors includes line numbers
    conf     *config         // parsed config
    confPath string          // path to the config file
    db       *pgxpool.Pool   // database connection pool
    schema   *psql.DBSchema  // database tables, columns and relationships
    qcompile *qcode.Compiler // qcode compiler
    pcompile *psql.Compiler  // postgres sql compiler
)

super-graph 开发

源码构建的方式

# yarn install dependencies and build the web ui
make build
# do this the only the time to setup the database
docker-compose run rails_app rake db:create db:migrate db:seed
# start super graph in development mode with a change watcher
docker-compose up

web ui

# yarn is needed to build the web ui
brew install yarn
# this is where the react app for the ui lives
cd internals/serv/web
# launch it in development mpde
yarn start

说明

以上是一个概述的说明,详细的处理还是仔细阅读下源码

参考资料

https://supergraph.dev/docs/internals

posted on 2020-05-23 17:02  荣锋亮  阅读(472)  评论(0编辑  收藏  举报

导航