当前位置: 首页 > 工具软件 > graphql-batch > 使用案例 >

graphql查询mysql_graphql查询方案优化

郭志
2023-12-01

graphql查询方案优化

起因

graphql API对外提供完整的接口文档,按需取数据的功能,对于接口联调和前端开发同学看来绝对是神器,但对于初看graphql的后台同学看来,这个取数据怎么取?对于一个两层结构的列表数据,我对列表中的每一项都取一次二级数据?这后台抗得住吗?

举个例子:我们有这样一个应用场景,我们要取一个用户列表,列表中每一项展示有3个字段id、name、friends,friends字段是一个数组,结果集中要做二层展开,展开成id、name,结果集如下:

{

"data": {

"userList": [

{

"id": "1",

"name": "Dan",

"friends": [

{

"id": "2",

"name": "Marie"

},

{

"id": "3",

"name": "Jessie"

}

]

},

{

"id": "2",

"name": "Marie",

"friends": [

{

"id": "1",

"name": "Dan"

}

]

},

{

"id": "3",

"name": "Jessie",

"friends": [

{

"id": "1",

"name": "Dan"

}

]

}

]

}

}

DB中数据结构如下,我们这里使用json文件存储数据,

用户信息表

{

"1": {

"id": "1",

"name": "Dan"

},

"2": {

"id": "2",

"name": "Marie"

},

"3": {

"id": "3",

"name": "Jessie"

}

}

用户关系表

{

"1":[

2,

3

],

"2":[

1

],

"3":[

1

]

}

DB层对外提供fakeDB.getAll获取用户列表接口,fakeDB.getFriendsInfo获取用户朋友信息接口,HTTP层再做一层封装,对外提供userBiz.getAll获取用户列表接口,userBiz.getFriendsInfo获取用户朋友信息接口,这样graphql中阶层获取数据请求数据的方式是先调用userBiz.getAll接口获取用户列表,再依次对每个用户调用一遍userBiz.getFriendsInfo接口获取列表每一项的friends字段,日志输出结果如下:

get all

get friends info1

get friends info2

get friends info3

这样列表项有多少项,就需要发起多少个userBiz.getFriendsInfo接口的HTTP调用,如果返回数据列表项再加大,数据层级再加深,HTTP调用的数量将会变得非常大,有没有办法减少HTTP调用呢,graphql实际上已经提供了解决方案

解决方案

graphql引入dataloader组件,提供合并请求的能力,dataloader的原理很简单,他利用nodejs的next tick机制,需要额外后台额外增加一个批量获取用户朋友信息的HTTP接口,修改graphql的schema,使其使用dataloader的方式,dataloader的具体配置详见附件代码,日志输出结果如下:

get all

get batch friends info 1,2,3

可见对列表项中的每一项获取friends信息合并成了一个HTTP请求

总结

这里假设的场景是一个graphql中间层调用HTTP接口的合并,如果使用graphql作为server端接口标准,同样可以使用dataloader合并sql层的访问

 类似资料: