GraphQL Mutation更新对象时如何保留未传入字段的原有值?
解决GraphQL Mutation更新时未传字段被清空的问题
你当前的Mutation解析器会直接替换目标对象,导致未传入的字段被清空。要实现「未声明的字段保留原有值」的效果,核心是基于原有对象做增量更新,而不是直接覆盖整个对象。
问题复现
现有解析器代码:
Mutation : { update(parent, args) => { links[args.id] = { description: args.description, url: args.url, } } }
当执行仅传入url的Mutation时:
mutation { update(id:0, url:"hello.com") { url } }
原有description字段会被清空,结果丢失了原有值。
正确实现方案
方案1:内联条件+对象展开(适合字段较少的场景)
通过对象展开保留原有字段,仅在args存在对应字段时覆盖:
Mutation: { update(parent, args) { // 先获取原有对象 const targetLink = links[args.id]; if (!targetLink) { throw new Error('指定ID的链接不存在'); } // 增量更新:保留原有字段,只覆盖传入的字段 links[args.id] = { ...targetLink, // 仅当args中存在description时才覆盖 ...(args.description !== undefined && { description: args.description }), // 仅当args中存在url时才覆盖 ...(args.url !== undefined && { url: args.url }) }; // 返回更新后的对象(符合GraphQL规范) return links[args.id]; } }
方案2:通用过滤更新(适合字段较多的场景)
如果以后可能新增更多字段,这种写法更灵活,无需逐个判断:
Mutation: { update(parent, args) { const targetLink = links[args.id]; if (!targetLink) throw new Error('指定ID的链接不存在'); // 过滤掉args中的id(仅保留需要更新的字段) const updateData = Object.fromEntries( Object.entries(args).filter(([key]) => key !== 'id') ); // 合并原有对象和更新字段 links[args.id] = { ...targetLink, ...updateData }; return links[args.id]; } }
你的尝试问题分析
你之前的写法逻辑完全反了,(!!args.description ? void(0) : args.description) 会在description存在时赋值为undefined,反而清空了字段;而且直接替换整个对象的写法本身就会丢失未传入的原有字段,所以无法达到预期效果。
内容的提问来源于stack exchange,提问作者Carlos
相关产品推荐
相关产品推荐

