如何查询所有的GraphQL类型字段而不写一个长查询?

假设你有一个GraphQL类型,它包含很多字段。 如何查询所有字段而不写下一个长查询,其中包括所有字段的名称?< / p >

例如,如果我有这些字段:

 public function fields()
{
return [
'id' => [
'type' => Type::nonNull(Type::string()),
'description' => 'The id of the user'
],
'username' => [
'type' => Type::string(),
'description' => 'The email of user'
],
'count' => [
'type' => Type::int(),
'description' => 'login count for the user'
]


];
}

要查询所有字段,查询通常是这样的:

FetchUsers{users(id:"2"){id,username,count}}

但我想要一种方法来获得相同的结果,而不需要写所有的字段,就像这样:

FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}

有没有办法在GraphQL中做到这一点??

我正在使用Folkloreatelier / laravel-graphql库。

243464 次浏览

我想做到这一点的唯一方法是利用可重用的片段:

fragment UserFragment on Users {
id
username
count
}


FetchUsers {
users(id: "2") {
...UserFragment
}
}

不幸的是,你想做的是不可能的。GraphQL要求您明确指定希望从查询中返回哪些字段。

当我需要从谷歌places API加载已序列化到数据库中的位置数据时,我也遇到了同样的问题。一般来说,我想要整个东西,这样它就能与map一起工作,但我不想每次都必须指定所有字段。

我在Ruby中工作,所以我不能给你PHP实现,但原则应该是相同的。

我定义了一个称为JSON的自定义标量类型,它只返回一个文字JSON对象。

ruby的实现是这样的(使用graphql-ruby)

module Graph
module Types
JsonType = GraphQL::ScalarType.define do
name "JSON"
coerce_input -> (x) { x }
coerce_result -> (x) { x }
end
end
end

然后我把它用在我们的对象上

field :location, Types::JsonType

不过我会非常谨慎地使用它,只在您知道总是需要整个JSON对象的地方使用它(就像我在我的例子中所做的那样)。否则,更一般地说,它会打败GraphQL的对象。

是的,你可以使用自省来做到这一点。创建一个GraphQL查询(对于类型UserType)

{
__type(name:"UserType") {
fields {
name
description
}
}
}

你会得到这样的响应(实际字段名取决于你实际的模式/类型定义)

{
"data": {
"__type": {
"fields": [
{
"name": "id",
"description": ""
},
{
"name": "username",
"description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
},
{
"name": "firstName",
"description": ""
},
{
"name": "lastName",
"description": ""
},
{
"name": "email",
"description": ""
},
( etc. etc. ...)
]
}
}
}

然后,您可以在客户机中读取这个字段列表,并动态构建第二个GraphQL查询以获取所有这些字段的值。

这依赖于您知道您想要获取字段的类型的名称——如果您不知道类型,您可以使用像这样的自省来获得所有类型和字段

{
__schema {
types {
name
fields {
name
description
}
}
}
}

注意:这是通过网线传输的GraphQL数据——您必须自己弄清楚如何使用实际的客户机进行读写。你的graphQL javascript库可能已经在某些方面使用了自省,例如阿波罗codegen命令使用自省来生成类型。

20222年更新

由于这个答案是最初编写的,所以现在建议在生产中使用关掉自省。参考:为什么应该在生产环境中禁用graphql自省

对于在生产环境中关闭内省的环境,您可以在开发中使用它作为一种方式来帮助创建在生产中使用的静态查询;实际上,您无法在生产环境中动态地创建查询。

GraphQL查询格式的设计是为了允许:

  1. 查询和结果形状都是完全一样
  2. 服务器知道完全请求的字段,因此客户端下载只有基本数据。

然而,根据GraphQL文档,你可以创建片段以使选择集更可重用:

# Only most used selection properties


fragment UserDetails on User {
id,
username
}

然后,您可以通过以下方式查询所有用户详细信息:

FetchUsers {
users() {
...UserDetails
}
}

你也可以在片段旁边添加其他字段:

FetchUserById($id: ID!) {
users(id: $id) {
...UserDetails
count
}
}

Package graphql-type-json支持定制标量类型JSON。 使用它可以显示json对象的所有字段。 下面是ApolloGraphql Server中的示例链接。 https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars < / p >