Как передать переменную в GraphQL для выбора полей

Мой пример запроса выглядит следующим образом:

%{
      "query" => """
        query getPerson(
            $name: String!
          ){
            getPerson(name: $name) {
              id
              col1
              col2
              col3
              col3
            }
          }
      """,
      "variables" => %{
        "name" => "person_name",
      }
    }

Я хочу выбирать поля динамически. Например, для одного запроса мне нужен только id, col1, col2, а для другого - id, col1, col3 и так далее. Как использовать переменную для полей?

Ниже я попробую, но это неверно.

%{
          "query" => """
            query getPerson(
                $name: String!
              ){
                getPerson(name: $name) {
                  $fields
                }
              }
          """,
          "variables" => %{
            "name" => "person_name",
            "fields" => "id col1 col3",
          }
        }

Я новичок в graphql. Кто-нибудь может помочь мне написать это правильно?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 614
3

Ответы 3

Запрос представляет собой простую старую хорошую строку, поэтому я бы пошел с интерполяцией строк в Elixir вместо того, чтобы пытаться использовать переменные GraphQL.

defmodule M do
  def query!(fields) when is_list(fields) do
    fields = Enum.join(fields, "\n        ")

    query =
      ~s"""
        query getPerson(
            $name: String!
          ){
            getPerson(name: $name) {
              #{fields}
            }
          }
      """
    %{
      "query" => query,
      "variables" => %{
        "name" => "person_name",
      }
    }
  end
end

И используйте его как M.query!(~w|id col1 col2|).

Мой текущий код похож на код, который вы дали выше. Я забыл упомянуть, что не хочу использовать строковую интерполяцию в запросе, если это возможно по какой-либо причине. Итак, я пытаюсь найти способ удалить #{fields} и использовать переменную.

Khaino 20.12.2018 07:43

Хотя я не мог представить себе причин для отказа от интерполяции строк, другим вариантом было бы использовать Absinthe.Schema.Notation.resolve/1, предоставляемый Абсент.

Aleksei Matiushkin 20.12.2018 08:03

Вы не можете сделать это изначально в GraphQL. Переменные предоставляют только определенные (входные) значения и не определяют структуру запроса. (То же самое верно в большинстве реализаций SQL.)

Вы можете прочитать грамматику в спецификации GraphQL, чтобы увидеть, что разрешено, например, в набор выбора; просто не разрешено использовать переменные так, как вы предлагаете.

Одна альтернатива, которая сводит к минимуму количество необходимых вам манипуляций со строками, - это использовать именованные фрагменты для упаковки списка запрошенных полей. Разрешено отправлять фрагменты, которые вы фактически не используете. Вы можете реструктурировать свой запрос как

fragment PersonParts on Person { id col1 col2 col3 }
query GetPerson($name: String!) {
  getPerson(name: $name) { ...PersonParts }
}

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

Вы можете использовать директиву @include для включения поля col2 на основе переменной флага:

query getPerson($name: String!, $withCol2: Boolean = false) {
  getPerson(name: $name) {
    id
    col1
    col2 @include(if: $withCol2)
    col3
  }
}

См. https://graphql.org/learn/queries/#directives

Другие вопросы по теме