Graphql-ruby: GraphQL ruby mutation using InputObject problem

Created on 3 Mar 2020  路  9Comments  路  Source: rmosolgo/graphql-ruby

Hi, I'm new with GraphQL ruby and I was able to make my mutation work without using the InputObject but manually defining all the arguments that I need then passing it via input: { . . . }.

I then stumbled with InputObject and seems that it is a more elegant way to implement my mutation by using the the query variables. However, I'm current stuck at it with these errors:

{
  "errors": [
    {
      "message": "Type mismatch on variable $input and argument input (UserInput! / createUserInput!)",
      "locations": [
        {
          "line": 2,
          "column": 22
        }
      ],
      "path": [
        "mutation createUser",
        "createUser",
        "input"
      ],
      "extensions": {
        "code": "variableMismatch",
        "variableName": "input",
        "typeName": "UserInput!",
        "argumentName": "input",
        "errorMessage": "Type mismatch"
      }
    }
  ]
}

Here's my mutation for creating a user.

# mutations/create_user.rb
mutation createUser($input: UserInput!) {
  createUser(input: $input) {
    firstname,
    lastname,
    email
  }
}
# query variables
{ 
     "input": {
          "firstname": "John",
      "lastname": "Doe",
      "email": "[email protected]"
       }
}

Here's my mutation/type classes:

# mutation class
module Mutations
  class CreateUser < BaseMutation
    graphql_name "createUser"

    argument :input, ProviderBff::Types::UserInput, required: true

    # return type from mutation
    type ProviderBff::Types::UserType

    def resolve(input:)
      # . . . rest of the codes
    end
  end
end
# InputType
module Types
    class UserInput < BaseInputObject
          graphql_name 'UserInput'

      argument :firstname, String, required: true
      argument :lastname, String, required: true
      argument :email, String, required: true
    end
  end
module Types
    class UserType < BaseObject
      graphql_name 'UserType'

      field :firstname, String, null: false
      field :lastname, String, null: false
      field :email, String, null: false
    end
  end

What seems to be the problem here?

Most helpful comment

Does your BaseMutation extend GraphQL::Schema::RelayClassicMutation?

If it does, change it to extend GraphQL::Schema::Mutation instead.

(RelayClassicMutation inserts an automatically-generated input: argument to your configured mutation. It looks like you're defining input: manually, so you don't need that generated argument. In fact, the generated argument is _getting in your way_!)

All 9 comments

Does your BaseMutation extend GraphQL::Schema::RelayClassicMutation?

If it does, change it to extend GraphQL::Schema::Mutation instead.

(RelayClassicMutation inserts an automatically-generated input: argument to your configured mutation. It looks like you're defining input: manually, so you don't need that generated argument. In fact, the generated argument is _getting in your way_!)

Does your BaseMutation extend GraphQL::Schema::RelayClassicMutation?

If it does, change it to extend GraphQL::Schema::Mutation instead.

(RelayClassicMutation inserts an automatically-generated input: argument to your configured mutation. It looks like you're defining input: manually, so you don't need that generated argument. In fact, the generated argument is _getting in your way_!)

Hi @rmosolgo, thank you for the quick response. Yes, the BaseMutation do extend the GraphQL::Schema::RelayClassicMutation.

I see, will try to remove the manual input: and will get back to you. Thanks

Hi @rmosolgo, tried to go deeper to understand it and it seems that everything is auto-generated when using RelayClassicMutation unless you supply a new value for them.

Anyway, I updated my mutation class to this

module Mutations
    class CreateUser < GraphQL::Schema::RelayClassicMutation

      # return type from mutation
      type Types::CreateUserType

      def resolve
        # rest of codes
      end
    end
  end

Looks like I'm getting there. However, I'm getting this error now:

{
  "errors": [
    {
      "message": "Variable $input of type CreateUserInput! was provided invalid value",
      "locations": [
        {
          "line": 1,
          "column": 29
        }
      ],
      "extensions": {
        "value": null,
        "problems": [
          {
            "path": [],
            "explanation": "Expected value to not be null"
          }
        ]
      }
    }
  ]
}

There are no null values within my query variables so why is it raising this error?

Could you please share the query string that you tried when you got that error?

Here's the query string @rmosolgo.

"{\"query\":\"mutation createUser($input: CreateUserInput!) {\\n createUser(input: $input) {\\n firstname,\\n lastname,\\n email\\n }\\n}\",\"variables\":{\"input\":{\"firstname\":\"fname\",\"lastname\":\"lname\",\"email\":\"[email protected]\"}},\"operationName\":\"createUser\"}"

Hm... that seems like it should work! Are you passing variables: params[:variables] in your GraphqlController? Could you share that code, please?

Hi @rmosolgo, thank you for responding quickly, really appreciated it. By the way this is not a Ruby on Rails project so we're not using any controllers, it's outside of rails so we're just using graphql-ruby gem.

Ok, then please share the code wherever you're calling .execute(...) to execute the GraphQL query. I want to check that variables are being given correctly.

(The values in your example _should_ work, so I wonder if they're not being passed to .execute(...) correctly.)

Hi again @rmosolgo, upon checking what's calling the .execute(..) seems that the variables aren't being passed to it. It's working perfectly now! :)

Thank you so much for assisting me. Will close this now!

Cheers!

Was this page helpful?
0 / 5 - 0 ratings