如何在不编写长查询的情况下查询所有 GraphQL 类型字段?
How to query all the GraphQL type fields without writing a long query?
假设您有一个 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 库。
我想做到这一点的唯一方法是利用可重复使用的片段:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
很遗憾,您无法完成您想做的事情。 GraphQL 要求您明确指定您希望从查询中返回哪些字段。
当我需要从 google 个位置 API 加载我已经序列化到数据库中的位置数据时,我遇到了同样的问题。通常我会想要整个东西,以便它可以与地图一起使用,但我不想每次都必须指定所有字段。
我在Ruby工作,所以我不能给你PHP实现,但原理应该是一样的。
我定义了一个名为 JSON 的自定义标量类型,它只是 returns 一个文字 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 的对象。
是的,您可以使用introspection执行此操作。进行 GraphQL 查询,例如 (for type UserType)
{
__type(name:"UserType") {
fields {
name
description
}
}
}
你会得到这样的回复(实际字段名称将取决于你的实际 schema/type 定义)
{
"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 查询以获取所有这些字段的值。
这取决于您知道要为其获取字段的类型的名称——如果您不知道该类型,您可以使用像[=15=这样的内省法将所有类型和字段放在一起]
{
__schema {
types {
name
fields {
name
description
}
}
}
}
注意:这是在线 GraphQL 数据——您需要自己弄清楚如何与您的实际客户端一起读取和写入。您的 graphQL javascript 库可能已经在某些方面使用了内省,例如 apollo codegen 命令使用内省来生成类型。
GraphQL query format 旨在允许:
- 查询和结果的形状完全相同。
- 服务器确切知道请求的字段,因此客户端仅下载基本数据。
然而,根据 GraphQL documentation, you may create 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
}
}
包 graphql-type-json 支持自定义标量类型 JSON。
使用它可以显示您的 json 对象的所有字段。
这是 ApolloGraphql Server 中示例的 link。
https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars
这个问题可以通过我前天发布的框架解决
https://github.com/babyfish-ct/graphql-ts-client
长查询:
const employees = findEmployees(
{},
employee$.
.id
.firstName
.lastName
.gender
.salary
.subordinates(
employee$.id
)
)
短查询(员工 $$ = 员工 $ + 所有标量字段):
const employees = findEmployees(
{},
employee$$.
.subordinates(
employee$.id
)
)
假设您有一个 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 库。
我想做到这一点的唯一方法是利用可重复使用的片段:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
很遗憾,您无法完成您想做的事情。 GraphQL 要求您明确指定您希望从查询中返回哪些字段。
当我需要从 google 个位置 API 加载我已经序列化到数据库中的位置数据时,我遇到了同样的问题。通常我会想要整个东西,以便它可以与地图一起使用,但我不想每次都必须指定所有字段。
我在Ruby工作,所以我不能给你PHP实现,但原理应该是一样的。
我定义了一个名为 JSON 的自定义标量类型,它只是 returns 一个文字 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 的对象。
是的,您可以使用introspection执行此操作。进行 GraphQL 查询,例如 (for type UserType)
{
__type(name:"UserType") {
fields {
name
description
}
}
}
你会得到这样的回复(实际字段名称将取决于你的实际 schema/type 定义)
{
"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 查询以获取所有这些字段的值。
这取决于您知道要为其获取字段的类型的名称——如果您不知道该类型,您可以使用像[=15=这样的内省法将所有类型和字段放在一起]
{
__schema {
types {
name
fields {
name
description
}
}
}
}
注意:这是在线 GraphQL 数据——您需要自己弄清楚如何与您的实际客户端一起读取和写入。您的 graphQL javascript 库可能已经在某些方面使用了内省,例如 apollo codegen 命令使用内省来生成类型。
GraphQL query format 旨在允许:
- 查询和结果的形状完全相同。
- 服务器确切知道请求的字段,因此客户端仅下载基本数据。
然而,根据 GraphQL documentation, you may create 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
}
}
包 graphql-type-json 支持自定义标量类型 JSON。 使用它可以显示您的 json 对象的所有字段。 这是 ApolloGraphql Server 中示例的 link。 https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars
这个问题可以通过我前天发布的框架解决
https://github.com/babyfish-ct/graphql-ts-client
长查询:
const employees = findEmployees(
{},
employee$.
.id
.firstName
.lastName
.gender
.salary
.subordinates(
employee$.id
)
)
短查询(员工 $$ = 员工 $ + 所有标量字段):
const employees = findEmployees(
{},
employee$$.
.subordinates(
employee$.id
)
)