如何构造GraphQL Mutation向Int列表添加元素并计算平均值(graph.cool&Apollo)
给Test模型的list添加值并计算平均值的实现方案
嘿,我来帮你搞定这个需求!结合Graph.cool和Apollo,你有两种可靠的实现方式,我分别给你拆解清楚:
方式一:服务端自定义Mutation(推荐,避免竞态问题)
这种方式把数组更新和平均值计算放在Graph.cool的服务端Resolver里处理,能避免多用户同时操作时的数据不一致问题。
1. 扩展GraphQL Schema
首先在你的Graph.cool Schema里添加一个自定义Mutation:
extend type Mutation { addIntToList(testId: ID!, value: Int!): Test }
2. 实现Resolver逻辑
在Graph.cool的Resolver中编写处理逻辑(以JavaScript为例):
async function addIntToList(parent, { testId, value }, ctx) { // 1. 获取目标Test记录 const targetTest = await ctx.db.query.test({ where: { id: testId } }); // 2. 处理数组:如果原list为空则初始化,否则追加新值 const updatedList = targetTest.list ? [...targetTest.list, value] : [value]; // 3. 计算新平均值(因为average是Int类型,这里用Math.round取整,可根据需求调整) const total = updatedList.reduce((sum, num) => sum + num, 0); const updatedAverage = Math.round(total / updatedList.length); // 4. 更新Test记录并返回结果 return ctx.db.mutation.updateTest({ where: { id: testId }, data: { list: updatedList, average: updatedAverage } }); }
3. Apollo客户端调用Mutation
在客户端定义Mutation文档:
mutation AddIntToList($testId: ID!, $value: Int!) { addIntToList(testId: $testId, value: $value) { id list average } }
然后在你的前端代码中(比如React)使用Apollo调用:
import { useMutation } from '@apollo/client'; import ADD_INT_TO_LIST from './graphql/mutations/addIntToList'; function AddValueComponent({ testId }) { const [addIntToList] = useMutation(ADD_INT_TO_LIST); const handleAddValue = (inputValue) => { addIntToList({ variables: { testId, value: inputValue } }); }; return ( <button onClick={() => handleAddValue(7)}> 添加7到列表并更新平均值 </button> ); }
方式二:客户端先查询再更新(适合简单场景)
如果你的应用不存在多用户并发更新的场景,也可以在客户端完成计算后直接调用Graph.cool的内置updateTest Mutation:
1. 查询当前Test记录的list
先获取目标Test的现有list数据:
query GetTestDetails($testId: ID!) { test(where: { id: $testId }) { id list } }
2. 计算新list和平均值
在客户端处理数据:
// 假设已经通过Apollo查询到了test数据 const currentList = testData.list || []; const newList = [...currentList, 5]; // 这里的5是要添加的Int值 const totalSum = newList.reduce((sum, num) => sum + num, 0); const newAverage = Math.round(totalSum / newList.length);
3. 调用内置updateTest Mutation
定义更新的Mutation文档:
mutation UpdateTest($testId: ID!, $newList: [Int!], $newAverage: Int!) { updateTest( where: { id: $testId }, data: { list: $newList, average: $newAverage } ) { id list average } }
然后在客户端执行这个Mutation即可。
注意点
- 因为
average是Int类型,计算时记得做取整处理(比如Math.round、Math.floor),避免返回浮点数导致类型错误。 - 优先选择服务端Resolver的方式,能有效避免并发更新时的竞态条件,保证数据一致性。
内容的提问来源于stack exchange,提问作者Josh Birdwell
相关产品推荐
相关产品推荐

