共计 4009 个字符,预计需要花费 11 分钟才能阅读完成。
人之初,性本鸽。
大家好,我叫储惠龙(实名上网),你能够叫我小龙人,00 后一枚。目前从事后端开发工作。
明天给大家带来一个简略的为 NebulaGraph 提供 GraphQL 查问反对的 DEMO,为什么是简略的,因为原本想实现更多工作再给大家介绍的,然而上个月太忙加上下个月更忙,然而我又很想白嫖一下 Nebula 官网的奖品,所以就连忙端上来了。
体验 NebulaGraphQL
先上我的项目地址:https://github.com/Dragonchu/NebulaGraphQL
GraphQL 是什么
先简略介绍一下 GraphQL,https://graphql.cn/ 具体的信息官网介绍得都很清晰。说一下我的了解,GraphQL 并不是对标 Cypher 这种查询语言,而是对标 REST 的一种 API 设计格调。
所以,严格意义上,不是说应用 GraphQL 查问图数据库,而是应用一种 GraphQL 格调的 API 查问图数据库,或者说是将 Cypher 封装了一样。这个实质工作和大家做利用开发时,基于 NebulaGraph 写一些通过的 REST 接口是一样的。
API 查问示例
本文的测试数据集应用的 NebulaGraph 官网的 basketballplayer 数据集 https://docs.nebula-graph.io/2.0/basketballplayer-2.X.ngql
举个例子,如果我想“依据科比的名字失去科比的全副信息”,可能会应用上面这样的 nGQL 语句:
LOOKUP ON player WHERE player.name == "Kobe Bryant" YIELD id(vertex) as vertexId | FETCH PROP ON player $-.vertexId YIELD properties(vertex);
尽管说 nGQL 曾经很不便浏览了,然而如果让一个齐全 0 根底的萌新来看也是看不懂的,并且这个语句的返回值是不明确的,至多没有方法从查问看到后果。而 返回值的解析始终也是很多人的苦楚。
那么,来看看应用 GraphQL 查问同一场景会是什么状况。
查问语句会是:
{players(name:"Kobe Bryant"){
name
age
}
}
返回后果是:
{players=[{name=Kobe Bryant, age=40}]
}
看看这优雅的查问和返回后果,想必我不多说,大家也都看得懂。这真的是
其实下面说了那么多,就是官网对 GraphQL 的总结:形容你的数据、申请你所要的数据、失去可预测的后果。
上述的查问在 NebulaGraphQL 中曾经实现了,同时还反对通过 VertexID 查问数据(好吧,我也就实现了这两种)。
NebulaGraphQL 简略入门
NebulaGraphQL 是一个 Java 库,旨在应用层提供 应用 GraphQL 语法查问 NebulaGraph 图数据库中数据 的能力。
在我的项目中应用 NebulaGraphQL 非常简单,因为 NebulaGraphQL 自身只想做一个简略的工具库,将来如果想间接集成到 MVC 框架可能会再起一个 NebulaGraphQL-Spring 之类的我的项目(画大饼中……)。所以 NebulaGraphQL 的应用和 nebula-java 是简直完全一致的。
应用示例:
// 创立一个 config
GraphqlSessionPoolConfig graphqlSessionPoolConfig = new GraphqlSessionPoolConfig(Lists.newArrayList(graphdAddress),
Lists.newArrayList(metadAddress),
spaceName, username, password);
// 创立一个连接池
GraphqlSessionPool pool = new GraphqlSessionPool(graphqlSessionPoolConfig);
// 执行语句
ExecutionResult executionResult = pool.execute("{players(age:32){name\nage}}");
// 获取后果
System.out.println(executionResult.getData().toString());
其实 GraphSessionPool
外部就是应用的 nebula-java 的 SessionPool,所有配置都和应用官网提供的连接池统一,惟一的区别是须要额定提供 metad 的连贯地址。这是因为 NebulaGraphQL 是通过 metad 来主动构建 Schema 的,NebulaGraphQL 会在创立连接池时主动创立 Schema。
NebulaGraphQL 的实现
NebulaGraphQL 次要是基于 graphql-java 实现的。而应用 graphql-java,大家能够依据本人的我的项目定义本人的 GraphQL 的 Schema。不过,NebulaGraphQL 想尽可能地提供一些通用性能,并且肯定是依据 NebulaGraph 的 Schema 主动构建的。
在创立 GraphqlSessionPool 时,NebulaGraphQL 通过连贯 NebulaGraphQL 的 metad 将 NebulaGraph 中的元数据信息结构成 GraphQL 的 Schema 信息。这一部分是要害难题。目前,我仅仅做了如下的变换:
- 对于 NebulaGraph 中所有的 Tag,都会结构一个对应的 GraphQL 的可查问对象。
- 每一个 Tag 都会有一个同名的依据 ID 获取信息的查问。举例来说,对于 player 这个 tag,会生成一个查问 player,这个查问的参数是 vertexID,会依据 vertexID 获取到信息。
- 每一个 Tag 都会有一个在名称后加
-s
的查问。举例来说,对于 player 这个 tag,会生成一个查问 players,这个查问的参数是任意的属性。如果 player 上有 age,name,country 这些属性,在查问参数中能够传入这三种属性的任意组合,NebulaGraphQL 查问时会将这些参数进行“与”AND
语义的结构,再获取相干顶点。对于用户没有指定的参数,默认为 null(这是一个已知的问题,如果目标就是查 null 会有问题)。
测试数据集上主动生成的 GraphQL 的 Schema 示例:
type Query {
player(
"Vertex ID"
ID: ID
): player
players(age: Int = null, name: String = null): [player]!
team(
"Vertex ID"
ID: ID
): team
teams(name: String = null): [team]!
}
type player {
age: Int
name: String
}
type team {name: String}
简略解说一下,Query 是 GraphQL 的查问入口,其中的 player, players, team, teams 都是主动生成的查问,能够当作查问语句。
player 是依据 VertexID 查问并返回一个 player,player 前面没有 !
标识符,阐明可能查问后果为空。players 查问有两个参数,对应着 player 这个 tag 的两个属性 age 和 name,这两个参数的类型都从 NebulaGraph 中的数据类型映射到了 GraphQL 的数据类型,默认值都为 null,返回值是一个列表。列表后的 !
,阐明肯定返回一个列表,然而其中的 player 后没有 !
标识符,指的是可能返回一个空列表。
应用 players 查问,参数能够指定 age 或者 name,或者 age 和 name 一起指定。
上面的 player 和 team 两个 type 就示意了这两个对象有什么属性,能够在查问时指定返回的属性,NebulaGraphQL 在返回后果时就只会提供查问须要的属性。
每一个 GraphQL 的查问会有一个绑定的 DataFetcher 对象,该对象中实现的就是如何将 GraphQL 语法映射成 nGQL 语句,并执行插叙返回后果。而返回后果会映射到自定义对象上,这里应用了我另一个小工具 NebulaResultBoot 将执行后果映射到自定的对象上后,咱们就能够在将来实现应用层的缓存,当然这里也有一个潜在的问题:每一次查问都要求获取到每一个点边的所有属性,这部分将来须要思考优化。
当然,NebulaGraphQL 的指标不只是简略将 nGQL 映射到 GraphQL 这么简略,因为 GraphQL 除了查问简略这个很清朗的特点,还能够更轻松的反对权限治理,以及通过 DataLoader 机制在应用层实现一层缓存。不过,我这边目前也没有钻研的很透彻,如果有大佬违心退出一起实现那就最好不过了。
为了不便大家奉献(次要是我懒),NebulaGraphQL 的开发测试曾经实现了一部分的容器化了,将代码库克隆到本地后,本地只须要有 Docker,而后在仓库根目录下运行
docker-compose -f docker-compose.dev.yml up --build
就能够看到在主动跑测试了,会在本地启动 NebulaGraph 集群并主动插入测试的数据,后续会持续优化这方面的流程。
小结
NebulaGraphQL 提供了更简略的查问语句,这个查问语句的结构应该是让前端间接提供的,GraphQL 的劣势之一就是能够让前端抉择本人须要的数据从而防止“接口天堂”,可能会有人认为这相当于让前端间接拜访数据库了。是的,我感觉这个了解也的确没问题,这也是有人拥护 GraphQL 的理由,不过这里就不持续探讨了。
然而应用 GraphQL 有一个潜在劣势,也就是能够更轻松的将图数据库和关系型数据库整合在一起。当然如果只是应用图数据库的话,那应用 NebulaGraphQL 至多也能不便做一些简略的数据查问与测试。
对于 NebulaGraphQL 在理论生产中的价值目前我也没有体验过,因为纯属趣味写着玩儿,如果大家有想法,欢送在评论区交换。