人之初,性本鸽。
大家好,我叫储惠龙(实名上网),你可以叫我小龙人,00后一枚。目前从事后端开发工作。
今天给大家带来一个简单的为NebulaGraph提供GraphQL查询支持的DEMO,为什么是简单的,因为本来想完成更多工作再给大家介绍的,但是上个月太忙加上下个月更忙,但是我又很想白嫖一下Nebula官方的奖品,所以就赶紧端上来了。
先上项目地址:https://github.com/Dragonchu/NebulaGraphQL
先简单介绍一下GraphQL,https://graphql.cn/ 详细的信息官方介绍的都很清晰。说一下我的理解,GraphQL并不是对标Cypher这种查询语言,而是对标REST的一种API设计风格。所以严格意义上,不是说使用GraphQL查询图数据库,而是使用一种GraphQL风格的API查询图数据库,或者说是将Cypher封装了一样,这个本质工作和大家做应用开发时,基于Nebula写一些通过的REST接口是一样的。
举个例子(本文的测试数据集使用的官方的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本身只想做一个简单的工具库,未来如果想直接集成到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主要是基于GraphQL-Java实现的,其实使用GraphQL-Java,大家可以根据自己的项目定义自己的GraphQL的schema,不过NebulaGraphQL想尽可能的提供一些通用功能,并且一定是根据Nebula的schema自动构建的。
当然,NebulaGraphQL的目标不只是简单将Ngql映射到GraphQL这么简单,因为GraphQL除了查询简单这个很明朗的特点,还可以更轻松的支持权限管理,以及通过DataLoader机制在应用层实现一层缓存,不过我这边目前也没有研究的很透彻,如果有大佬愿意加入一起实现那就最好不过了。
为了方便大家贡献(主要是我懒),NebulaGraphQL的开发以及完成了一部分的容器化了,将代码库克隆到本地后,本地只需要有docker,然后在仓库根目录下运行
docker-compose -f docker-compose.dev.yml up --build
就可以看到在自动跑测试了,会在本地启动Nebula集群并自动插入测试的数据,后续会继续优化这方面的流程。
NebulaGraphQL提供了更简单的查询语句,这个查询语句的构造应该是让前端直接提供的,GraphQL的优势之一就是可以让前端选择自己需要的数据从而避免“接口地狱”,可能会有人认为这相当于让前端直接访问数据库了。是的,我觉得这个理解也确实没问题,这也是有人反对GraphQL的理由,不过这里就不继续讨论了。
但是使用GraphQL有一个潜在优势,也就是可以更轻松的将图数据库和关系型数据库整合在一起。当然如果只是使用图数据库的话,那使用NebulaGraphQL至少也能方便做一些简单的数据查询与测试。
其实对于NebulaGraphQL在实际生产中的价值目前我也没有体验过,因为纯属兴趣写着玩儿,如果大家有想法,欢迎在评论区交流。