Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有动态键的对象的Apollo/GraphQL字段类型_Graphql_Apollo_Apollo Server - Fatal编程技术网

具有动态键的对象的Apollo/GraphQL字段类型

具有动态键的对象的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是根据我的查询动态生成的(即查询中使用

假设我的graphql服务器希望以JSON的形式获取以下数据,其中
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 So
b
g
是id。也许我应该在问题中更清楚地说明这一点。查询将包含仅获取人员子集的选项,因此对于一个查询,响应将包含id为
a
b
的人员,
c
和另一个查询,例如问题中的
b
g
。@DanielRearden我现在将
b
更改为
person3
,将
g
更改为
person5
,并添加了一些文本和变量以使其更清晰。查询将包含仅获取文本中所述人员子集的选项。感谢您的评论!我转换来自服务器的传入数据。仅供参考:使用id的对象的原因是客户端检索速度更快,因为它只是查找id以访问特定的人。我的情况是通过Rails/GraphQL API返回验证错误。我事先不知道哪些键会有错误,因此我使用的是自定义JSON标量。实际上,我改变了使用嵌套数组的方法,使我能够一致地返回有错误的字段。