写点什么

graphql 计算指令之 @filter:查询中实现集合过滤

用户头像
coder_xy
关注
发布于: 3 小时前

问题背景

在使用 graphql 进行查询的时候,很多场景需要对 list 类型字段进行过滤筛选,例如过滤下架的商品、年龄不满 18 岁的用户、余量为 0 的优惠券等。


如下查询,如果要过滤未在售(onSale==false)的商品,需要在硬编码实现。


query itemListByIds($ItemIds:[Int]){    commodity{        itemList(itemIds: $ItemIds){            itemId            onSale            name            salePrice        }    }}
复制代码

解决方案

graphql 提供了指令机制,该机制类似于 java 注解,可用于 graphql 查询执行能力的动态拓展。


定义对列表数据记性过滤的指令:predicate:过滤判断表达式,结果为 true 的元素会被保留。


directive @filter(predicate: String!) on FIELD
复制代码


修改后的查询为:


query filterUnSaleCommodity($ItemIds:[Int]){    commodity{        filteredItemList: itemList(itemIds: $ItemIds)        # 只保留在售的商品        @filter(predicate: "onSale")        {            itemId            onSale            name            salePrice        }    }}
复制代码

具体实现

该能力可通过graphql-java-calculator进行实现,该组件基于指令系统、为 graphql 查询提供数据编排、动态计算和控制流的能力。


Config wrapperConfig = DefaultConfig.newConfig().build();
DefaultGraphQLSourceBuilder graphqlSourceBuilder = new DefaultGraphQLSourceBuilder();GraphQLSource graphqlSource = graphqlSourceBuilder .wrapperConfig(wrapperConfig) .originalSchema( // 原始schema对象 GraphQLSourceHolder.getDefaultSchema() ).build();
String query = "" + "query filterUnSaleCommodity($itemIds:[Int]){\n" + " commodity{\n" + " itemList(itemIds: $itemIds)\n" + " @filter(predicate: "onSale")\n" + " {\n" + " itemId\n" + " onSale\n" + " name\n" + " salePrice\n" + " }\n" + " \n" + " }\n" + "}";ExecutionInput input = ExecutionInput .newExecutionInput(query) .variables(Collections.singletonMap("itemIds", Arrays.asList(1, 2, 3))) .build();
ExecutionResult result = graphqlSource.getGraphQL().execute(input);
复制代码


完整示例参考Example

联系反馈

欢迎大家试用graphql-java-calculator,笔者毕业后一直从事 graphql 的平台化工作,graphql-java组件的活跃 contributor,期待使用反馈建议。

发布于: 3 小时前阅读数: 6
用户头像

coder_xy

关注

还未添加个人签名 2018.03.27 加入

还未添加个人简介

评论

发布
暂无评论
graphql计算指令之@filter:查询中实现集合过滤