Как принять JSON в запросах Absinthe GraphQL - PullRequest
0 голосов
/ 07 января 2019

Я пытаюсь получить строку JSON в моей реализации graphql, но продолжаю получать ошибки с пользовательским скаляром, который я определил для обработки JSON.

Я определил пользовательский скаляр для правильной сериализации JSON в карту эликсира. Я получаю сообщения об ошибках, которые имеют недопустимые типы данных, прежде чем мой код достигнет стадии синтаксического анализа пользовательского скаляра. Я пытаюсь использовать https://github.com/absinthe-graphql/absinthe/wiki/Scalar-Recipes#json-using-jason для создания скаляра, однако я изменил использование Яда вместо Джейсона.

Мой мутатор абсента использует скалярный тип: json, который я создал.

@desc "Update user"
field :update_user, type: :user do
  arg(:email, :string)
  arg(:password, :string)
  arg(:first_name, :string)
  arg(:last_name, :string)
  arg(:age, :integer)
  arg(:client_store, :json)

  resolve(handle_errors(&Resolvers.User_Resolver.update_user/3))
end

Мое скалярное определение и определение схемы graphql

    scalar :json, name: "Json" do
        description("""
        The `Json` scalar type represents arbitrary json string data, represented as UTF-8
        character sequences. The Json type is most often used to represent a free-form
        human-readable json string.
        """)
        serialize(&encode/1)
        parse(&decode/1)
    end

    # @spec decode(Absinthe.Blueprint.Input.String.t) :: {:ok, :string} | :error
    # @spec decode(Absinthe.Blueprint.Input.Null.t) :: {:ok, nil}
    defp decode(%Absinthe.Blueprint.Input.String{value: value}) do
        Logger.info "decoded input value:"
        case Poison.decode(value) do
        {:ok, result} -> {:ok, result}
        _ -> :error
        end
    end

    defp decode(%Absinthe.Blueprint.Input.Null{}) do
        {:ok, nil}
    end

    defp decode(_) do
        :error
    end

    defp encode(value), do: value

    object :user do
        field(:id, :id)
        field(:email, :string)
        field(:password, :string)
        field(:first_name, :string)
        field(:last_name, :string)
        field(:age, :integer)
        field(:client_store, :json)
    end

при отправке следующих запросов:

    mutation updateUser{
      updateUser(client_store: "{"key":"value"}"){
        id
      }
    }

Я получаю syntax error before: \"\\\":\\\"\"

    mutation updateUser{
      updateUser(client_store: "hello"){
        id
      }
    }

Я получаю "Argument \"client_store\" has invalid value \"hello\"

Отправка запроса GraphQL через модульный тест по Phoenix.ConnTest

query = """
    mutation updateUser{
      updateUser(client_store: "{\"key\":\"value\"}"){
        id
      }
    }
  """

res =
  context.conn
  |> put_req_header("content-type", "text")
  |> put_req_header("authorization", token)
  |> post("/api", query)

Ответы [ 2 ]

0 голосов
/ 08 июля 2019

Я тестирую вот так

  test "should get an existing key" do
    {:ok, user} = Api.Auth.Users.create_user(%{name: "Test User"})
    {:ok, app} = Api.Auth.Apps.create_app(%{owner_id: %{type: :user, id: user.id}, name: "name"})
    {:ok, key} = Api.Auth.Keys.create_key(%{app_id: app.id})

    %{resp_body: response} =
      build_conn()
      |> post("graphql", %{
        "query" => """
          query {
            key(id: "#{key.id}") {
              id
            }
          }
        """
      })

    %{"data" => %{"key" => %{"id" => id}}} = Jason.decode!(response)

    assert key.id == id
  end
end
0 голосов
/ 07 января 2019

Проблема с вашей мутацией, вам нужно экранировать кавычки внутри строки, например:

mutation updateUser{
  updateUser(client_store: "{\"key\": \"value\"}"){
    id
  }
}

В противном случае интерпретация заключается в том, что вторая кавычка отмечает конец строки, поэтому в основном у вас есть строка "{", за которой следует key":"value"}", что является синтаксически недопустимым.

Обратите внимание, что при отправке мутации в модульном тесте вы уже определяете мутацию как строку, поэтому вам нужно дополнительно экранировать кавычки:

query = """
    mutation updateUser{
      updateUser(client_store: "{\\\"key\\\":\\\"value\\\"}"){
        id
      }
    }
  """

Поначалу это может быть немного сложно понять, но распечатка проясняет:

iex(1)> """
...(1)>     mutation updateUser{
...(1)>       updateUser(client_store: "{\"key\":\"value\"}"){
...(1)>         id
...(1)>       }
...(1)>     }
...(1)> """ |> IO.puts()
    mutation updateUser{
      updateUser(client_store: "{"key":"value"}"){
        id
      }
    }

iex(2)> """
...(2)>     mutation updateUser{
...(2)>       updateUser(client_store: "{\\\"key\\\":\\\"value\\\"}"){
...(2)>         id
...(2)>       }
...(2)>     }
...(2)> """ |> IO.puts() 
    mutation updateUser{
      updateUser(client_store: "{\"key\":\"value\"}"){
        id
      }
    }

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

...