Как запросить все поля типа GraphQL без написания длинного запроса?

Предположим, что у вас есть тип 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.

+49
10 дек. '15 в 10:50
источник поделиться
4 ответа

К сожалению, то, что вы хотели бы сделать, невозможно. GraphQL требует, чтобы вы явно указывали, какие поля вы хотели бы вернуть из своего запроса.

+45
11 дек. '15 в 15:03
источник

Да, вы можете сделать это с помощью самоанализа. Сделайте запрос 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 уже может использовать интроспекцию в некоторой степени, например, команда apollo codegen использует интроспекцию для генерации типов.

+37
31 мая '17 в 15:36
источник

Я предполагаю, что единственный способ сделать это - использовать повторно используемые фрагменты:

fragment UserFragment on Users {
    id
    username
    count
} 

FetchUsers {
    users(id: "2") {
        ...UserFragment
    }
}
+21
10 дек. '15 в 15:08
источник

Я столкнулся с этой же проблемой, когда мне нужно было загружать данные о местоположении, которые я сериализовал в базе данных из API google places. В общем, я бы хотел, чтобы все это работало с картами, но я не хотел указывать все поля каждый раз.

Я работал в 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.

+6
15 янв. '17 в 12:52
источник

Посмотрите другие вопросы по меткам или Задайте вопрос