Предположим, у вас есть тип 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 библиотека.
К сожалению, то, что вы хотели бы сделать, невозможно. 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 по проводам — вы сами можете выяснить, как читать и писать с вашим реальным клиентом. Ваша библиотека JavaScript JavaScript graphQL уже может использовать интроспекцию в некоторой степени, например Аполлон Codegen Команда использует самоанализ для генерации типов.
Я думаю, что единственный способ сделать это — использовать повторно используемые фрагменты:
fragment UserFragment on Users {
id
username
count
}
FetchUsers {
users(id: "2") {
...UserFragment
}
}
Я столкнулся с этой же проблемой, когда мне нужно было загрузить данные о местоположении, которые я сериализовал, в базу данных из API мест Google. Как правило, я хотел бы, чтобы все это работало с картами, но я не хотел каждый раз указывать все поля.
Я работал в 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 в более общем смысле.