Tsuna
Tsuna

Reputation: 2196

is there possible chance to pass array of objects (json) as input field for mutation? graphene-python

I am trying to pass json field as input for my graphql mutation. I have been trying and searching but just no luck. I can pass array fine with I know by defining graphene.List(graphene.String) would work for passing array of strings.

I figured there's a type named graphene.JSONstring() which I thought would work if I use it with graphene.List(graphene.JSONstring) but no luck, still getting errors saying type is not right.

I have something like this during the mutation

    mutation {
        create(data:{
                field1: [
                    {
                        "first": "first",
                        "last": "last"
                    },
                    {
                        "first":"first1",
                        "last":"last1"
                    }
                ]
        })
    }

as for input class

class NameInput(graphene.InputObjectType):
    # please ignore the same field names, just listing what I have tried
    field1 = graphene.JSONString()  
    field1 = graphene.List(graphene.JSONString)
    field1 = graphene.List(graphene.String)

Does anyone has an idea how this would work?

Thanks in advance

Upvotes: 3

Views: 2994

Answers (3)

mrpandey
mrpandey

Reputation: 1029

Graphene provides a GenericScalar type. You can use it to input/output generic types like int, str, dict, list, etc.

from graphene import InputObjectType, Mutation
from graphene.types.generic import GenericScalar

class InputObject(InputObjectType):
    field1 = GenericScalar()

class Create(Mutation):
    class Arguments:
        data = InputObject()

    def mutate(root, info, data):
        # do something with data.field1

Then your input would look like

mutation {
  create (
    data: {
      field1: [
        {
          first: "first",
          last: "last"
        },
        {
          first: "first1",
          last: "last1"
        }
      ]
    }
  )
}

Note that field1 can accept any generic input, so make sure to validate it.

Also, when using a GenericScalar field for output (query), you won't be able to query its subfields. But you can write a resolver for that field to make sure only specific subfields are returned.

Here is the link to the corresponding GitHub issue.

Upvotes: 0

noName
noName

Reputation: 1

You could try like this:

class NameInput(graphene.InputObjectType):
    field1 = graphene.JSONString()

And then:

mutation {
    create(data:{
            field1: "[
                {
                    \"first\": \"first\",
                    \"last\": \"last\"
                },
                {
                    \"first\":\"first1\",
                    \"last\":\"last1\"
                }
            ]"
    })
}

So basically send json as string.

Upvotes: 0

Herku
Herku

Reputation: 7666

Seems like you are trying to have nested input objects. Unfortunately I have never used graphene but maybe I can answer in terms of the GraphQL specification and then make an educated guess about the graphene code:

type Mutation {
  create(data: NameInput): Boolean # <- Please don't return just Boolean
}

input NameInput {
  field1: FistLastInput[]
}

input FirstLastInput {
  first: String!
  last: String!
}

This means you will need two input objects to describe the structure of your input. Create a new class for you object that takes the fields first and last:

class FirstLastInput(graphene.InputObjectType):
    first = graphene.NonNull(graphene.String)
    last = graphene.NonNull(graphene.String)

Now we can use the input object in our initial query:

class NameInput(graphene.InputObjectType):
    field1 = graphene.List(FirstLastInput)

Upvotes: 1

Related Questions