正文
设计思想
之所以名称中包含有Graph,是因为GraphQL采用了图结构的查询方式。以一个例子来看:
我们想要设计一个公司的内部人员管理系统,假设一种最简单的场景,至少会包含部门和员工两大信息。以图的结构来表示他们的关系的话,可能会是这样:
回顾常用的系统会发现,基本都可以通过图来描述角色关系。这里,我们可以类比
图数据库
的概念。由于图的结构更接近于自然世界,相比关系型数据库,在设计图数据库时,会省去一个图结构向关系型结构的转化工作。关于图数据库的更多介绍,可以参考
neo4j的介绍
。
回到上图,假设我们现在要查询员工L某的详细信息,用GraphQL,可以这样来请求(为更加直观,这里以中文来表示):
{
员工(ID: "022") {
姓名
职位
所属部门 {
名称
}
同事 {
ID
姓名
职位
}
}
}
正常情况下,服务端返回的结果是:
{
员工 {
姓名: "L某",
职位: "员工",
所属部门:{
名称: "前端部"
}
同事:[
{
ID: "022",
姓名: "S某",
职位: "经理"
},
{
ID: "033",
姓名: "Y某",
职位: "总监"
}
]
}
}
可以看到,根据查询请求,员工的信息以Json的格式全部返回出来了。对应到图中,其实是提取了蓝色的这部分信息:
查询以员工(L某)为起点,沿着边,将所需的关联数据提取出来,形成了最终的返回的结果。由此可以看出,GraphQL所做的,其实是将
图结构的数据提取出成为一个树状结构
。为了更清晰的体现这一点,我们将蓝色部分单独取出来,并稍稍换一下节点的位置:
这里,可能会有个疑问:这样查询出的树状结构,必然要求涉及的节点之间有边。
如果我想要同时查询两个节点的信息,但它们间没有边,那该怎么办呢?
仍以之前的例子来看,如果我想查询员工L某和设计部的信息,但它们之间没有边。这种时候,可以构建一个虚拟的节点,并以它为起点,连接起其他需要查询的节点。大概会是这样的一种结构:
查询结构:
{
员工(ID: "022") {
姓名
职位
...
}
部门(名称: "设计部") {
名称
}
}
返回结果:
{
员工 {
姓名: "L某",
职位: "员工",
...
}
部门 {
名称: "设计部"
}
}
在实际的应用开发中,也通常采用以上这样的设计结构。
到此,我们来总结一下。GraphQL通过查询语句,将图结构的数据,提取成了树状结构作为结果返回。这里的图结构的数据,对应的便是GraphQL的
类型系统
。而如何将图中的节点,也就是定义的各个类型相互关联,需要通过具体的逻辑代码来实现。官方和社区也提供了各种语言的
GraphQL库
。