I'm attempting to receive a string of JSON in my graphql implementation but keep getting errors with the custom scalar I've defined to handle the JSON.
I've defined a custom scalar to properly serialize the JSON to an elixir map. I'm getting errors that I have invalid data types before my code reaches the parsing stage of the custom scalar. I'm attempting to use https://github.com/absinthe-graphql/absinthe/wiki/Scalar-Recipes#json-using-jason to create the scalar however I've modified to use Poison instead of Jason.
My absinthe mutator using the :json scalar type I created.
@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
My scalar definition and graphql schema definition
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
when sending the following queries:
mutation updateUser{
updateUser(client_store: "{"key":"value"}"){
id
}
}
I receive a syntax error before: \"\\\":\\\"\"
mutation updateUser{
updateUser(client_store: "hello"){
id
}
}
I receive a "Argument \"client_store\" has invalid value \"hello\"
Sending the GraphQL query through a unit test via 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)
The problem is with your mutation, you need to escape the quotes inside the string, like this:
mutation updateUser{
updateUser(client_store: "{\"key\": \"value\"}"){
id
}
}
Otherwise, the interpretation is that the second quote marks the end of the string, so you basically have the string "{"
followed by key":"value"}"
, which is syntatically invalid.
Note that when sending the mutation in an unit test, you are defining the mutation as a string already, so you need to further escape the quotes:
query = """
mutation updateUser{
updateUser(client_store: "{\\\"key\\\":\\\"value\\\"}"){
id
}
}
"""
This may be a little tricky to understand at first, but printing it makes it clearer:
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
}
}
So the last one works because when the string is evaluated, the result is the original mutation, which escapes the quotes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With