如何用GraphQL Mutation保存异构结构的cells数组?
问题描述
我有一个包含异构结构的JSON对象(cells数组),结构如下:
"cells": [ { "x":3, "y":6 }, { "type": "shape", "direction": "right" }, .... { "a": 4, "b": 5, "c": 6 } ]
我尝试用以下GraphQL类型定义编写Mutation来保存这个对象,但无法正常工作:
type A { x: Int! y: Int! } type B { type: String! direction: String! } type C { a: Int! b: Int! c: Int! } union Request = A | B | C input InputR { cells: [Request!]! } type Mutation { save(cells: InputR!): InputR }
错误原因
GraphQL规范明确规定:Union类型仅能作为输出类型使用(比如Query/Mutation的返回值、Object类型的字段),不能作为Input类型的成员。你试图在InputR里使用[Request!]!(Request是Union),这违反了规范,所以无法通过校验。
解决方案
针对异构Input数组的场景,有几种可行的处理方式:
方案1:使用带鉴别字段的单Input类型
定义一个包含所有可能字段的CellInput,用type字段作为鉴别器,在Resolver中根据type校验对应字段的必填性:
input CellInput { # 鉴别字段,用于区分不同类型的cell type: String! # 对应原A类型的字段 x: Int y: Int # 对应原B类型的字段 direction: String # 对应原C类型的字段 a: Int b: Int c: Int } type Mutation { # 直接接收CellInput数组 save(cells: [CellInput!]!): [CellInput!]! }
Resolver逻辑示例:
在处理save时,遍历每个cell:
- 如果
type为"position"(自定义标识),校验x和y是否存在且为整数 - 如果
type为"shape",校验direction是否存在 - 如果
type为"custom",校验a、b、c是否存在
方案2:使用JSON标量类型
如果你的GraphQL服务器支持JSON标量(比如Apollo Server自带JSON标量,或自定义标量),可以直接接收原始JSON数组,在Resolver中自行解析和校验:
# 定义JSON标量(若服务器未自带) scalar JSON type Mutation { save(cells: [JSON!]!): [JSON!]! }
这种方式灵活性最高,但需要自行处理结构校验,适合字段结构频繁变化的场景。
方案3:自定义Input Union(部分服务器支持)
部分GraphQL工具(如@graphql-tools/schema)支持通过扩展实现Input Union,但这属于非标准特性,需要额外配置。例如:
input AInput { x: Int! y: Int! } input BInput { type: String! direction: String! } input CInput { a: Int! b: Int! c: Int! } # 使用自定义指令或工具定义Input Union union CellInput = AInput | BInput | CInput type Mutation { save(cells: [CellInput!]!): [CellInput!]! }
注意:这种方式需要服务器端配置对应的解析逻辑,不同工具实现方式不同,需参考对应文档。
内容的提问来源于stack exchange,提问作者Max
相关产品推荐
相关产品推荐

