Graphql-ruby: [Question] How to create a mutation without `input` field?

Created on 4 Apr 2017  路  9Comments  路  Source: rmosolgo/graphql-ruby

I want to create a mutation, likes:

mutation createPost($title: String!, $body: String!) {
  createPost(title: $title, body: $body) {
    id
  }
}

When I create by rails g graphql:mutation CreatePost, and then use it with:

Types::MutationType = GraphQL::ObjectType.define do
  name 'Mutation'

  field :createPost, field: Mutations::CreatePost.field
end

It generate a mutation:

mutation createPost($input: CreatePost!) {
  createPost(input: $input) {
    id
  }
}

It just has one argument, needs less code, sometimes easy to write. But I want it seems like a function with some arguments.
How to expand the input argument to its fields when use GraphQL::Relay::Mutation?

If I define with below:

Types::MutationType = GraphQL::ObjectType.define do
  name 'Mutation'

  field :createPost do
    argument :title, !types.String
    argument :body, !types.String
    resolve -> (...) {...}
  end
end

How to separate fields to files in this way?

Most helpful comment

All Relay mutations have an input argument, so you can't use Relay::Mutation for this.

I think you might like GraphQL::Function (API, guide), how does that look?

All 9 comments

All Relay mutations have an input argument, so you can't use Relay::Mutation for this.

I think you might like GraphQL::Function (API, guide), how does that look?

@rmosolgo thanks. I will try it.

feel free to reopen this if it doens't work for you!

I tried and read document about functions. It only can use builtin types for arguments. So if I want use custom types, and I don't want see input, do I must define the field with a block likes below?

  field :createPost do
    argument :title, !types.String
    argument :body, !types.String
    resolve -> (...) {...}
  end

only can use builtin types

Is that right? It should support _any_ type!

This is my code:

class Functions::SignUp < GraphQL::Function
  type Types::UserInfoType

  argument :email, !types.String
  argument :password, !types.String

  def call(obj, args, ctx)
    UserInfo.new
  end
end
Types::MutationType = GraphQL::ObjectType.define do
  name 'Mutation'

  field :signUp, function: Functions::SignUp.new
end

Some errors happen:

NameError (undefined local variable or method `types' for Functions::SignUp:Class
Did you mean?  type
               @type):

When I change types.String to GraphQL::STRING_TYPE, it works.

And I found a section in document https://rmosolgo.github.io/graphql-ruby/schema/code_reuse#types :

Note that types. is not available. Instead, you should reference GraphQL鈥檚 built-in GraphQL::ScalarTypes directly.

And I found types. can be use in QueryType at https://rmosolgo.github.io/graphql-ruby/schema/code_reuse#extending-functions, but I want all code in that function.

Where did I wrong?

Oh, my documentation there is not good enough! How about this:

class Functions::SignUp < GraphQL::Function
  type Types::UserInfoType

  argument :email, GraphQL::STRING_TYPE.to_non_null_type
  argument :password, GraphQL::STRING_TYPE.to_non_null_type

  def call(obj, args, ctx)
    UserInfo.new
  end
end

:thinking: Maybe I should just support types. within function classes ...

Oh, I see. User defined types can be used, just not support types.*. I'd happy if you support that. ;-)

I think the change should be straightforward. GraphQL::Function needs a class method called .types which returns GraphQL::Define::TypeDefiner.instance, similar to this #types method. Then, the existing test function could be extended to include the use of types.*.

Feel free to take a try if you have the time!

Was this page helpful?
0 / 5 - 0 ratings