php 如何在不编写长查询的情况下查询所有 GraphQL 类型字段?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34199982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to query all the GraphQL type fields without writing a long query?
提问by BlackSigma
Assume you have a GraphQL type and it includes many fields. How to query all the fields without writing down a long query that includes the names of all the fields?
假设您有一个 GraphQL 类型并且它包含许多字段。如何在不写下包含所有字段名称的长查询的情况下查询所有字段?
For example, If I have these fields :
例如,如果我有这些字段:
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'
]
];
}
To query all the fields usually the query is something like this:
要查询所有字段,通常查询是这样的:
FetchUsers{users(id:"2"){id,username,count}}
But I want a way to have the same results without writing all the fields, something like this:
但我想要一种无需编写所有字段即可获得相同结果的方法,如下所示:
FetchUsers{users(id:"2"){*}}
//or
FetchUsers{users(id:"2")}
Is there a way to do this in GraphQL ??
有没有办法在 GraphQL 中做到这一点?
I'm using Folkloreatelier/laravel-graphqllibrary.
我正在使用Folkloreatelier/laravel-graphql库。
采纳答案by Peter Horne
Unfortunately what you'd like to do is not possible. GraphQL requires you to be explicit about specifying which fields you would like returned from your query.
不幸的是,您想要做的事情是不可能的。GraphQL 要求您明确指定您希望从查询中返回哪些字段。
回答by Mark Chackerian
Yes, you cando this using introspection. Make a GraphQL query like (for type UserType)
是的,您可以使用introspection来做到这一点。进行 GraphQL 查询,例如(对于UserType 类型)
{
__type(name:"UserType") {
fields {
name
description
}
}
}
and you'll get a response like (actual field names will depend on your actual schema/type definition)
并且您会得到类似的响应(实际字段名称将取决于您的实际架构/类型定义)
{
"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. ...)
]
}
}
}
You can then read this list of fields in your client and dynamically build a second GraphQL query to get all of these fields.
然后,您可以在客户端中读取此字段列表,并动态构建第二个 GraphQL 查询以获取所有这些字段。
This relies on you knowing the name of the type that you want to get the fields for -- if you don't know the type, you could get all the types and fields together using introspection like
这取决于您知道要为其获取字段的类型的名称 - 如果您不知道类型,则可以使用内省将所有类型和字段放在一起,例如
{
__schema {
types {
name
fields {
name
description
}
}
}
}
NOTE: this is the over-the-wire GraphQL data -- you're on your own to figure out how to read and write with your actual client. Your graphQL javascript library may already employ introspection in some capacity, for example the apollo codegencommand uses introspection to generate types.
注意:这是在线 GraphQL 数据——您需要自己弄清楚如何使用您的实际客户端进行读写。您的 graphQL javascript 库可能已经在某些方面使用了自省,例如apollo codegen命令使用自省来生成类型。
回答by tommy
I guess the only way to do this is by utilizing reusable fragments:
我想做到这一点的唯一方法是利用可重用的片段:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
回答by Tyrone Wilson
I faced this same issue when I needed to load location data that I had serialized into the database from the google places API. Generally I would want the whole thing so it works with maps but I didn't want to have to specify all of the fields every time.
当我需要加载我从 google Places API 序列化到数据库中的位置数据时,我遇到了同样的问题。一般来说,我想要整个东西,所以它适用于地图,但我不想每次都指定所有的字段。
I was working in Ruby so I can't give you the PHP implementation but the principle should be the same.
我在 Ruby 中工作,所以我不能给你 PHP 实现,但原理应该是一样的。
I defined a custom scalar type called JSON which just returns a literal JSON object.
我定义了一个名为 JSON 的自定义标量类型,它只返回一个文字 JSON 对象。
The ruby implementation was like so (using graphql-ruby)
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
Then I used it for our objects like so
然后我像这样将它用于我们的对象
field :location, Types::JsonType
I would use this very sparingly though, using it only where you know you always need the whole JSON object (as I did in my case). Otherwise it is defeating the object of GraphQL more generally speaking.
不过,我会非常谨慎地使用它,仅在您知道您总是需要整个 JSON 对象的地方使用它(就像我在我的情况下所做的那样)。否则,更一般地说,它是在打败 GraphQL 的对象。
回答by JP Ventura
GraphQL query formatwas designed in order to allow:
GraphQL 查询格式旨在允许:
- Both query and result shape be exactly the same.
- The server knows exactlythe requested fields, thus the client downloads onlyessential data.
- 查询和结果形状完全相同。
- 服务器准确地知道请求的字段,因此客户端只下载必要的数据。
However, according to GraphQL documentation, you may create fragmentsin order to make selection sets more reusable:
但是,根据GraphQL 文档,您可以创建片段以使选择集更可重用:
# Only most used selection properties
fragment UserDetails on User {
id,
username
}
Then you could query all user details by:
然后您可以通过以下方式查询所有用户详细信息:
FetchUsers {
users() {
...UserDetails
}
}
You can also add additional fields alongside your fragment:
FetchUserById($id: ID!) {
users(id: $id) {
...UserDetails
count
}
}
回答by PokerFace
Package graphql-type-json supports custom-scalars type JSON. Use it can show all the field of your json objects. Here is the link of the example in ApolloGraphql Server. https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars
包 graphql-type-json 支持自定义标量类型 JSON。使用它可以显示您的 json 对象的所有字段。这是 ApolloGraphql Server 中示例的链接。 https://www.apollographql.com/docs/apollo-server/schema/scalars-enums/#custom-scalars