如何将变量传递给GraphQL以选择字段

时间:2018-12-20 02:53:25

标签: elixir 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的新手。谁能帮我正确写出来?

3 个答案:

答案 0 :(得分:2)

您不能在GraphQL中本地执行此操作。变量仅提供特定的(输入)值,而不定义查询的结构。 (在大多数SQL实现中也是如此。)

您可以通读GraphQL规范中的语法,以查看selection set中允许的内容;只是不允许按照您的建议使用变量。

使您需要做的字符串操作量最小化的另一种方法是使用named fragments打包请求字段的列表。可以发送您实际上不使用的片段。您可以将查询重组为

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

,如果您有多个命名片段,则将其替换掉,而不是尝试动态构造字段列表。

答案 1 :(得分:1)

查询中有一个普通的旧字符串,因此我将在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|)

答案 2 :(得分:0)

您可以使用 @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