graphql-elixir / graphql

GraphQL Elixir
Other
858 stars 45 forks source link

undefined function: nil.type/0 when repoducing the example from docs [0.0.6] #26

Closed ivan-kolmychek closed 8 years ago

ivan-kolmychek commented 8 years ago

I'm trying to reproduce the example from docs with some small changes, but I get an error when I try to execute sample request.

My schema:

defmodule BlogSchema do
  def schema do
    %GraphQL.Schema{
      query: %GraphQL.ObjectType{
        name: "RootQueryType",
        fields: [ 
          %GraphQL.FieldDefinition{name: :post, type: "String", resolve: &post/0}
        ]   
      }   
    }   
  end 

  def post do
    "test"
  end 
end

Request:

GraphQL.execute(BlogSchema.schema, "{post}")

Trace

             nil.type()
             lib/graphql/execution/executor.ex:79: GraphQL.Execution.Executor.resolve_field/4
             lib/graphql/execution/executor.ex:66: anonymous fn/5 in GraphQL.Execution.Executor.execute_fields/4
    (stdlib) lists.erl:1262: :lists.foldl/3
             lib/graphql/execution/executor.ex:37: GraphQL.Execution.Executor.execute_operation/3
             lib/graphql/execution/executor.ex:17: GraphQL.Execution.Executor.execute/5

I'm not sure, but it looks like executor.ex:79 expects fields to be a map, but gets an array instead.

But when I change my schema to

defmodule BlogSchema do
  def schema do
    %GraphQL.Schema{
      query: %GraphQL.ObjectType{
        name: "RootQueryType",
        fields: %{
          post: %GraphQL.FieldDefinition{name: :post, type: "String", resolve: &post/0}
        }
      }   
    }   
  end 

  def post do
    "test"
  end 
end

I get this error

** (BadArityError) #Function<0.112413074/0 in BlogSchema.schema/0> with arity 0 called with 3 arguments (%{}, %{}, %{field_asts: [%{kind: :Field, loc: %{start: 0}, name: "post"}], field_name: "post", fragments: %{}, operation: %{kind: :OperationDefinition, loc: %{start: 0}, operation: :query, selectionSet: %{kind: :SelectionSet, loc: %{start: 0}, selections: [%{kind: :Field, loc: %{start: 0}, name: "post"}]}}, parent_type: %GraphQL.ObjectType{description: "", fields: [post: %GraphQL.FieldDefinition{args: %{}, name: :post, resolve: #Function<0.112413074/0 in BlogSchema.schema/0>, type: "String"}], name: "RootQueryType"}, return_type: "String", root_value: %{}, schema: %GraphQL.Schema{mutation: nil, query: %GraphQL.ObjectType{description: "", fields: [post: %GraphQL.FieldDefinition{args: %{}, name: :post, resolve: #Function<0.112413074/0 in BlogSchema.schema/0>, type: "String"}], name: "RootQueryType"}}, variable_values: %{}})
             lib/graphql/execution/executor.ex:94: GraphQL.Execution.Executor.resolve_field/4
             lib/graphql/execution/executor.ex:66: anonymous fn/5 in GraphQL.Execution.Executor.execute_fields/4
    (stdlib) lists.erl:1262: :lists.foldl/3
             lib/graphql/execution/executor.ex:37: GraphQL.Execution.Executor.execute_operation/3
             lib/graphql/execution/executor.ex:17: GraphQL.Execution.Executor.execute/5

So now resolve function we've got from field definition is called with three arguments.

What am I doing wrong?

ivan-kolmychek commented 8 years ago

Ok, I've redefined my schema to

defmodule BlogSchema do
  def schema do
    %GraphQL.Schema{
      query: %GraphQL.ObjectType{
        name: "RootQueryType",
        fields: %{
          post: %GraphQL.FieldDefinition{name: :post, type: "String", resolve: &post/3}
        }
      }   
    }   
  end 

  def post(_, _, _) do
    "test"
  end 
end

and now I do receive the correct response

iex(8)> GraphQL.execute(BlogSchema.schema, "{post}")
{:ok, %{"post" => "test"}}

Was it intended for the resolve function to have three arguments exactly?

ivan-kolmychek commented 8 years ago

Ok, found how args are defined and passed.

defmodule BlogSchema do
  def schema do
    %GraphQL.Schema{
      query: %GraphQL.ObjectType{
        name: "RootQueryType",
        fields: %{
          post: %GraphQL.FieldDefinition{
            name: :post, 
            type: "String", 
            args: %{ id: "String" },
            resolve: &post/3}
        }
      }   
    }   
  end 

  def post(_, args, _) do
    "test"
  end 
end

I think, documentation should really be updated. :)

joshprice commented 8 years ago

Thanks for picking this up, I've fixed the docs in the plug, I'll make sure all other docs are updated! Sorry for any inconvenience. :(

ivan-kolmychek commented 8 years ago

@joshprice not a problem, I'm just messing around, so, just wanted to report my findings.

I'm not sure it's convinient for devs to have resolving function with arity 3. At least we should put args as a first argument, I guess.

ivan-kolmychek commented 8 years ago

Also, in what format should arguments be defined in schema? I mean, what should be the respecing values set to, just "String", or any type, or something completely different?

ivan-kolmychek commented 8 years ago

@joshprice if I understand correctly, type is ignored currently. Am I right?

I guess, this should be included in docs too, at least as a "checkbox"-like thing (like [WIP] arguments type validation/coercion or something like that).

joshprice commented 8 years ago

Docs updated, that should be all of it I think

joshprice commented 8 years ago

Types will be the next thing I'll be working, thanks for the feedback!

ivan-kolmychek commented 8 years ago

Thanks.