写点什么

graphql 中的'子查询'

用户头像
杜艮魁
关注
发布于: 3 小时前
graphql中的'子查询'

问题背景

本文介绍 对于在某一业务场景中有依赖关系的信息、如何通过一个 graphql 查询返回关联数据。


mysql 中的子查询

mysql 中的子查询:当查询执行时,首先执行子查询并返回一个结果集。然后,将此结果集作为外部查询的输入。例如有活动表和商品表,查询出商品类活动涉及的商品信息如下:


-- 参与活动的商品信息select * from commodity_info_tablewhere id ink(    -- 活动类型为 "commodity" 时、该id为商品id    select item_id    -- 包含活动类型、涉及主体id、活动开始时间、结束时间等    from activity_info_table    -- activity_type_code 为活动类型    where activity_type_code = "commodity")
复制代码


graphql 中的子查询

上述数据往往会有 商品 和 活动 两个研发小组维护,并通过接口提供服务。既无法通过子查询直接查询 DB,也不可能存在<font color = red> 获取所有活动商品详情数据</font>的接口


如果活动接口数据和商品接口数据治理到 graphql 平台上,原生的 graphql 查询也难以通过一个查询直接获取这种关联数据。一般解决方案为使用两次查询解决,两次 io、并需要有相应的硬编码、硬逻辑支持:


graphql查询活动数据 ——>   解析活动中的商品id  ——> graphql查询商品数据。
复制代码


解决方案

示例 schema

对于上述问题存在如下 graphql schema 定义:


type Query{    activityInfo(activityType:String): Actitivy    commodityList(commodityIds:[Int]): Commodity}
type Actitivy{ id: Int itemId: Int activityType: String # ...}
type Commodity{ id: Int name: String price: Int}
复制代码


定义计算指令

graphql 提供了指令机制用于 graphql 查询执行能力的动态拓展、指令机制类似于 java 中的注解。我们通过定义‘源数据指令’和‘参数转换指令’实现数据之间的依赖传递


directive @argumentTransform(argumentName:String!, operateType:ParamTransformType!, expression:String!, dependencySources:[String!]) on FIELD
enum ParamTransformType{ MAP # 参数转换 FILTER # 列表类型参数过滤 LIST_MAP # 列表类型参数元素转换}
复制代码


指令具体说明可参考graphql-calculator-README。通过指令实现的 graphql“子查询”如下:


query getActivityCommodityInfo{    # 根据活动类型获取活动信息  activityInfo(activityType:"commodity"){    # 将 活动商品id注册为源数据    itemId @fetchSource(name:"itemIdList")  }    commodityList(commodityIds: 1)  @argumentTransform(    argumentName:"commodityIds", # 进行转换的参数名称    operateType:MAP,expression:"itemIdList", # 转换类型和表达式    dependencySources:"itemIdList" # 依赖的源数据  ){    id    # ......   }}
复制代码

参考资料

用户头像

杜艮魁

关注

wx:dugenkui 2018.03.27 加入

快手电商营销团队研发工程师,欢迎使用、关注graphql-calculator:https://github.com/dugenkui03/graphql-java-calculator

评论

发布
暂无评论
graphql中的'子查询'