假设您有一个GraphQL类型,它包含许多字段。 如何在不写下包含所有字段名称的长查询的情况下查询所有字段?
例如,如果我有这些字段:
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 库。
答案 0 :(得分:55)
不幸的是,你不想做什么。 GraphQL要求您明确指定要从查询中返回的字段。
答案 1 :(得分:53)
是的,您可以使用introspection执行此操作。创建一个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库可能已经在某种程度上使用了内省,例如apollo codegen命令使用内省来生成类型。
答案 2 :(得分:24)
我想这样做的唯一方法是利用可重复使用的片段:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
答案 3 :(得分:6)
当我需要从Google Places API加载我已经序列化到数据库中的位置数据时,我遇到了同样的问题。一般来说,我会想要整个事情,所以它适用于地图,但我不想每次都指定所有字段。
我在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的对象。
答案 4 :(得分:0)
GraphQL query format旨在实现以下目的:
但是,根据GraphQL documentation,您可以创建fragments以便使选择集更可重用:
# Only most used selection properties
fragment UserDetails on User {
id,
username
}
然后,您可以通过以下方式查询所有用户详细信息:
FetchUsers {
users() {
...UserDetails
}
}
您也可以add additional fields alongside your fragment:
FetchUserById($id: ID!) {
users(id: $id) {
...UserDetails
count
}
}
答案 5 :(得分:0)
哈哈,你的问题可以用我前天发布的框架解决
https://github.com/babyfish-ct/graphql-ts-client
长查询:
const employees = findEmployees(
{},
employee$.
.id
.firstName
.lastName
.gender
.salary
.subordinates(
employee$.id
)
)
简短查询(employee$$ = employee$ + 所有标量字段):
const employees = findEmployees(
{},
employee$$.
.subordinates(
employee$.id
)
)