具有动态键的对象的Apollo/GraphQL字段类型
假设我的graphql服务器希望以JSON的形式获取以下数据,其中具有动态键的对象的Apollo/GraphQL字段类型,graphql,apollo,apollo-server,Graphql,Apollo,Apollo Server,假设我的graphql服务器希望以JSON的形式获取以下数据,其中person3和person5是一些id: "persons": { "person3": { "id": "person3", "name": "Mike" }, "person5": { "id": "person5", "name": "Lisa" } } 问题:如何使用apollo创建模式类型定义 此处的键person3和person5是根据我的查询动态生成的(即查询中使用
person3
和person5
是一些id:
"persons": {
"person3": {
"id": "person3",
"name": "Mike"
},
"person5": {
"id": "person5",
"name": "Lisa"
}
}
问题:如何使用apollo创建模式类型定义
此处的键person3
和person5
是根据我的查询动态生成的(即查询中使用的区域
)。所以在另一个时间我可能会得到person1
,person2
,person3
返回。
正如您所看到的persons
不是一个Iterable,因此下面的graphql类型定义与我对apollo所做的定义不同:
type Person {
id: String
name: String
}
type Query {
persons(area: String): [Person]
}
persons
对象中的键可能总是不同的
当然,一种解决方案是将传入的JSON数据转换为使用
人员的数组,但是没有办法这样处理数据吗?GraphQL依赖于服务器和客户端提前知道每种类型的可用字段。在某些情况下,客户机可以发现这些字段(通过内省),但对于服务器,它们总是需要提前知道。因此,基于返回的数据以某种方式动态生成这些字段实际上是不可能的
可以使用自定义(graphql类型的json模块)并为查询返回:
type Query {
persons(area: String): JSON
}
通过使用JSON,您可以绕过对返回数据的要求,以适应任何特定的结构,因此只要JSON格式正确,您就可以发送回任何您想要的内容
当然,这样做有很大的缺点。例如,您丢失了以前使用过的类型所提供的安全网(实际上,任何结构都可以返回,如果返回的是错误的结构,则在客户端尝试使用它并失败之前,您将无法找到它)。您还无法对返回数据中的任何字段使用解析程序
但是。。。你的葬礼:)
作为一个旁白,我会考虑把数据放在一个数组中(就像你在你的问题中建议的那样),然后再把它发送回客户机。如果您正在编写客户机代码,并使用动态大小的客户列表,那么使用数组可能比使用id键控的对象更容易。例如,如果您使用React并为每个客户显示一个组件,您最终将该对象转换为数组以映射它。在设计API时,我会将客户端可用性作为比避免额外处理数据更重要的考虑因素。您可以编写自己的GraphQLScalarType
,并精确描述您的对象和动态键、允许和不允许或转换的内容
看
你可以看看他在哪里创建了一个标量,允许并转换任何类型的内容:
我在模式中遇到了类似的动态键问题,最终得到了如下解决方案:
query lookupPersons {
persons {
personKeys
person3: personValue(key: "person1") {
id
name
}
}
}
返回:
{
data: {
persons: {
personKeys: ["person1", "person2", "person3"]
person3: {
id: "person3"
name: "Mike"
}
}
}
}
通过将复杂性转移到查询,它简化了响应形状。
与JSON方法相比,它的优点是不需要从客户端进行任何反序列化您能否澄清一下,根据我的查询动态生成的b
和g
是什么意思?是否存在一个或另一个取决于请求中存在的字段?@DanielRearden Sob
和g
是id。也许我应该在问题中更清楚地说明这一点。查询将包含仅获取人员子集的选项,因此对于一个查询,响应将包含id为a
,b
的人员,c
和另一个查询,例如问题中的b
和g
。@DanielRearden我现在将b
更改为person3
,将g
更改为person5
,并添加了一些文本和变量以使其更清晰。查询将包含仅获取文本中所述人员子集的选项。感谢您的评论!我转换来自服务器的传入数据。仅供参考:使用id的对象的原因是客户端检索速度更快,因为它只是查找id以访问特定的人。我的情况是通过Rails/GraphQL API返回验证错误。我事先不知道哪些键会有错误,因此我使用的是自定义JSON标量。实际上,我改变了使用嵌套数组的方法,使我能够一致地返回有错误的字段。