Graphql-go: unable to parse schema: type of kind OBJECT can not be used as input

Created on 1 Nov 2017  路  8Comments  路  Source: graph-gophers/graphql-go

Looks like being able to pass a custom object as an input value is not allowed although it appears to be part of the graphql api:

http://graphql.org/learn/queries/#mutations

Is this something that's planned or would you be willing to accept a pull request for this?

Most helpful comment

So I arrived here after a quick googling and wondered what was wrong, and wished OP has posted how he solved :).

So here is how:
I wrote the Input type as:

type MyInput {
  ...
}

And it should be:

input MyInput {
  ...
}

All 8 comments

Whoops. User error.

So I arrived here after a quick googling and wondered what was wrong, and wished OP has posted how he solved :).

So here is how:
I wrote the Input type as:

type MyInput {
  ...
}

And it should be:

input MyInput {
  ...
}

I am pretty sure this is like the fifth time I come to this bug to realize my mistake as well :crying_cat_face: . It would be nice if the error message contained something like "Maybe you meant to use 'input XXX' instead of 'type XXX' in your schema?"

Hello Folks, I'm getting similar error and tried everything within my knowledge by going through whatever I could find online. Please let me know what I'm missing here.

Error:

panic: field "Pet": type of kind OBJECT can not be used as input
        used by (*resolver.RootResolver).AddPet

I have schema defined in a different package, below is my schema:

const Schema = `schema {
    mutation: Mutation
}

type Pet {
    id: String!
    name: String!
    tag: String!
}

input PetInput {
    id: String!
    name: String!
    tag: String!
}

type Mutation {
    addPet(pet: PetInput!): Pet!
}`

Here is my resolver code:

type RootResolver3 struct {
    p *model.Pet
}

func (r *RootResolver3) AddPet(ctx context.Context, args *PetInput) (*model.Pet, error) {
     // some code
}

func (pet *RootResolver3) Id(ctx context.Context) *string {
    return &pet.p.Id
}
func (pet *RootResolver3) Name(ctx context.Context) *string {
    return &pet.p.Name
}
func (pet *RootResolver3) Tag(ctx context.Context) *string {
    return &pet.p.Tag
}

Not sure how you got from an almost working solution in #381 to this one. :)

I assume your PetInput is defined as this:

type PetInput struct {
  ID string
  Name string
  Tag string
}

If that is not the case please include it.

The error message is because you are defining args as a pointer of type PetInput, when it should actually be defined like

args struct {
  Pet PetInput
}

In GraphQL the input parameters are named and can be provided in any order. That's why you need the additional struct.

I even guess your args can be defined as

args struct {
  Pet model.Pet
}

Based on your schema, there is no difference between Pet and PetInput. So it is most likely that you can use the same struct for both GraphQL types.

Furthermore your AddPet method returns *model.Pet but at the same time your resolver declares methods for receiving the ID, name and tag. You most likely want to return a PetResolver which implements these methods or enable resolving fields directly from your model.Pet in the options when parsing your schema.

There are good examples provided for simple issues like these in the readme.

Thanks @stefanberkner for the detailed reply. I was able to get through https://github.com/graph-gophers/graphql-go/issues/381 but ended up here. Hope I'm not running in circles. :)

Initially I was using the single struct as you mentioned to avoid redundancy. I had Pet as type and input in Schema but it was not working so thought of having separate PetInput.
Maybe I should have posted that error.

I reverted back to single struct Pet

type Pet struct {
    Id   string
    Name string
    Tag  string
}

Added Pet as input in Schema:

type Pet {
    id: String!
    name: String!
    tag: String!
}

input Pet {
    id: String!
    name: String!
    tag: String!
}

type Mutation {
    addPet(input: Pet!): Pet!
}

To add further, as my server is running with UseFieldResolvers(), I removed the extra methods from the resolver. Now my Resolver looks like this:

type RootResolver struct {
}

func (r *RootResolver) AddPet(ctx context.Context, args struct{ Input *model.Pet }) (*model.Pet, error)

This throws below error:
panic: invalid type: Pet

If I use args struct{ Pet model.Pet }, still the error persists.

Your code, without the pointers, should be correct. But now you renamed PetInput into Pet in your schema, which causes it to be declared twice, once as type and once as input. Please note, that in order to work, you can still use the same struct in go, but have two different definitions in your schema.

This is perfectly fine:
Schema

type ThisIsMyPetType {
  id: String
}
input AndMyPetInput {
  id: String
}

Go

type Pet struct {
  ID string
}

Afaik there is no verification of your struct and type names.

If that still doesn't help, please create a small repo to show the issue.

@stefanberkner Looks like I was making a rookie mistake with the graphql schema definition. Thanks for being patient. It worked after I changed the input name in schema to PetInput.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bsr203 picture bsr203  路  6Comments

Melaninneal picture Melaninneal  路  5Comments

rogchap picture rogchap  路  5Comments

AndreasBackx picture AndreasBackx  路  4Comments

0xTanvir picture 0xTanvir  路  5Comments