7

I'm trying to follow along this article on how to create a mutation on a rails server using GraphQl https://www.howtographql.com/graphql-ruby/4-authentication

However, I'm stuck at the CreateUser Mutation step, I get the follow error hash when trying it out in GraphiQL:

{
  "errors": [
    {
      "message": "Field 'createUser' is missing required arguments: input",
      "locations": [
        {
          "line": 45,
          "column": 3
        }
      ],
      "path": [
        "mutation CreateUser",
        "createUser"
      ],
      "extensions": {
        "code": "missingRequiredArguments",
        "className": "Field",
        "name": "createUser",
        "arguments": "input"
      }
    },
    {
      "message": "Field 'createUser' doesn't accept argument 'username'",
      "locations": [
        {
          "line": 46,
          "column": 5
        }
      ],
      "path": [
        "mutation CreateUser",
        "createUser",
        "username"
      ],
      "extensions": {
        "code": "argumentNotAccepted",
        "name": "createUser",
        "typeName": "Field",
        "argumentName": "username"
      }
    },
    {
      "message": "Field 'createUser' doesn't accept argument 'authProvider'",
      "locations": [
        {
          "line": 47,
          "column": 5
        }
      ],
      "path": [
        "mutation CreateUser",
        "createUser",
        "authProvider"
      ],
      "extensions": {
        "code": "argumentNotAccepted",
        "name": "createUser",
        "typeName": "Field",
        "argumentName": "authProvider"
      }
    },
    {
      "message": "Variable $username is declared by CreateUser but not used",
      "locations": [
        {
          "line": 44,
          "column": 1
        }
      ],
      "path": [
        "mutation CreateUser"
      ],
      "extensions": {
        "code": "variableNotUsed",
        "variableName": "username"
      }
    },
    {
      "message": "Variable $email is declared by CreateUser but not used",
      "locations": [
        {
          "line": 44,
          "column": 1
        }
      ],
      "path": [
        "mutation CreateUser"
      ],
      "extensions": {
        "code": "variableNotUsed",
        "variableName": "email"
      }
    },
    {
      "message": "Variable $password is declared by CreateUser but not used",
      "locations": [
        {
          "line": 44,
          "column": 1
        }
      ],
      "path": [
        "mutation CreateUser"
      ],
      "extensions": {
        "code": "variableNotUsed",
        "variableName": "password"
      }
    }
  ]
}

I just followed the code in the article, my files:

create_user.rb

module Mutations
  class CreateUser < BaseMutation
    # often we will need input types for specific mutation
    # in those cases we can define those input types in the mutation class itself
    class AuthProviderSignupData < Types::BaseInputObject
      argument :credentials, Types::AuthProviderCredentialsInput, required: false
    end

    argument :username, String, required: true
    argument :auth_provider, AuthProviderSignupData, required: false

    type Types::UserType

    def resolve(username: nil, auth_provider: nil)
      User.create!(
        username: username,
        email: auth_provider&.[](:credentials)&.[](:email),
        password: auth_provider&.[](:credentials)&.[](:password)
      )
    end
  end
end

user_type.rb

module Types
  class UserType < BaseObject
    field :id, ID, null: false
    field :email, String, null: false
    field :username, String, null: false
    field :photo, String, null: true
    field :phone, String, null: false
    field :island, IslandType, null: false, method: :island
    field :archipel, ArchipelType, null: false, method: :archipel

    field :created_at, String, null: false
    field :updated_at, String, null: false
  end
end

I have no clue where this 'input' thing is coming from.

Hugo
  • 2,073
  • 6
  • 23
  • 46
  • https://github.com/rmosolgo/graphql-ruby/blob/cfb9442c4a5fe0e869c367d299dcd4475ebd7bf9/lib/graphql/schema/relay_classic_mutation.rb#L12 ? – xadm Feb 28 '20 at 20:32

3 Answers3

21

Without realizing I inilialized my project with a configuration that used Relay.

By commenting this code inside my **_schema.rb file it worked again.

  # Opt in to the new runtime (default in future graphql-ruby versions)
  # use GraphQL::Execution::Interpreter
  # use GraphQL::Analysis::AST

  # Add built-in connections for pagination
  # use GraphQL::Pagination::Connections

As well as these lines inside base_mutation.rb and replaces with these.

  # class BaseMutation < GraphQL::Schema::RelayClassicMutation
  #   argument_class Types::BaseArgument
  #   field_class Types::BaseField
  #   input_object_class Types::BaseInputObject
  #   object_class Types::BaseObject
  # end

  class BaseMutation < GraphQL::Schema::Mutation
    null false
  end
Hugo
  • 2,073
  • 6
  • 23
  • 46
  • 10
    The important thing here which I missed was changing the inherited class from `GraphQL::Schema::RelayClassicMutation` to `GraphQL::Schema::Mutation` – koosa Feb 10 '21 at 19:24
  • 1
    Nice, thanks for sharing. Just adding: BaseMutation is generated by "rails g graphql:install". I struggled after reading this answer because I did not remember that this file exists in my project! – heringer May 10 '21 at 17:53
6

If you're not interested in commenting out fields... I ran across the same error. For whatever reason input is the name of the key you pass your arguments into as a hash/object.

Example from using this tutorial:https://www.howtographql.com/graphql-ruby/3-mutations/

mutation {
  createLink(input: {
    url: "foo",
    description:"bar"
  }) {
    url
    description
  }
}
Stephen
  • 337
  • 2
  • 7
  • a little confused by your answer here. It seems like `input` is not mentioned anywhere on that tutorial you linked – Peter Ehrlich Feb 28 '23 at 19:54
  • Yup, that’s why I left this answer in the first place. It’s been a while since I posted my answer. If you’re finding different results maybe something updated. – Stephen Mar 01 '23 at 21:01
0

@Stephen's solution worked for me (and I upvoted) but I didn't even realize it was the solution. I understood what Stephen was saying after I resolved this myself.

Basically, for some graphql libraries due to their default settings, you have to use the keyword input: { ... } in the mutation argument.

E.g., instead of using url: "foo" as argument

mutation {
  createLink(
    url: "foo"
  ) 
  ...
}

You need to use input: { url: "foo" }

mutation {
  createLink(
    input: { url: "foo" }
  )
  ...
}
nethsix
  • 800
  • 8
  • 17