Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

graphql-go : Use an Object as Input Argument to a Query

Tags:

go

graphql

I'm attempting to pass an object as an argument to a query (rather than a scalar). From the docs it seems that this should be possible, but I can't figure out how to make it work.

I'm using graphql-go, here is the test schema:

var fileDocumentType = graphql.NewObject(graphql.ObjectConfig{
Name: "FileDocument",
Fields: graphql.Fields{
    "id": &graphql.Field{
        Type: graphql.String,
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
                return fileDoc.Id, nil
            }
            return "", nil
        },
    },
    "tags": &graphql.Field{
        Type: graphql.NewList(tagsDataType),
        Args: graphql.FieldConfigArgument{
            "tags": &graphql.ArgumentConfig{
                Type: tagsInputType,
            },
        },
        Resolve: func(p graphql.ResolveParams) (interface{}, error) {
            fmt.Println(p.Source)
            fmt.Println(p.Args)
            if fileDoc, ok := p.Source.(data_format.FileDocument); ok {
                return fileDoc.Tags, nil
            }
            return nil, nil
        },
    },

},
})

And the inputtype I'm attempting to use (I've tried both an InputObject and a standard Object)

var tagsInputType = graphql.NewInputObject(graphql.InputObjectConfig{
Name: "tagsInput",
Fields: graphql.Fields{
    "keyt": &graphql.Field{
        Type: graphql.String,
    },
    "valuet": &graphql.Field{
        Type: graphql.String,
    },
},
})

And here is the graphql query I'm using to test:

{
        list(location:"blah",rule:"blah")
        {
            id,tags(tags:{keyt:"test",valuet:"test"})
            {
                key,
                value
            },
            {
                datacentre,
                handlerData
                {
                    key,
                    value
                }
            }
        }
    }

I'm getting the following error:

wrong result, unexpected errors: [Argument "tags" has invalid value {keyt: "test", valuet: "test"}.
In field "keyt": Unknown field.
In field "valuet": Unknown field.]

The thing is, when I change the type to a string, it works fine. How do I use an object as an input arg?

Thanks!

like image 874
user2851943 Avatar asked Nov 01 '16 13:11

user2851943


People also ask

How do you input in GraphQL?

To make your schema simpler, you can use “input types” for this, by using the input keyword instead of the type keyword. id: ID! Here, the mutations return a Message type, so that the client can get more information about the newly-modified Message in the same request as the request that mutates it.

How do you pass multiple arguments in GraphQL query?

Multiple arguments can be used together in the same query. For example, you can use the where argument to filter the results and then use the order_by argument to sort them.


1 Answers

Had the same issue. Here is what I found from going through the graphql-go source.

The Fields of an InputObject have to be of type InputObjectConfigFieldMap or InputObjectConfigFieldMapThunk for the pkg to work.

So an InputObject would look like this :

var inputType = graphql.NewInputObject(
    graphql.InputObjectConfig{
        Name: "MyInputType",
        Fields: graphql.InputObjectConfigFieldMap{
            "key": &graphql.InputObjectFieldConfig{
                Type: graphql.String,
            },
        },
    },
) 

Modified the Hello World example to take an Input Object :

package main

import (
    "encoding/json"
    "fmt"
    "log"

    "github.com/graphql-go/graphql"
)

func main() {
    // Schema

    var inputType = graphql.NewInputObject(
        graphql.InputObjectConfig{
            Name: "MyInputType",
            Fields: graphql.InputObjectConfigFieldMap{
                "key": &graphql.InputObjectFieldConfig{
                    Type: graphql.String,
                },
            },
        },
    )

    args := graphql.FieldConfigArgument{
        "foo": &graphql.ArgumentConfig{
            Type: inputType,
        },
    }

    fields := graphql.Fields{
        "hello": &graphql.Field{
            Type: graphql.String,
            Args: args,
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                fmt.Println(p.Args)
                return "world", nil
            },
        },
    }
    rootQuery := graphql.ObjectConfig{
        Name:   "RootQuery",
        Fields: fields,
    }

    schemaConfig := graphql.SchemaConfig{Query: graphql.NewObject(rootQuery)}
    schema, err := graphql.NewSchema(schemaConfig)
    if err != nil {
        log.Fatalf("failed to create new schema, error: %v", err)
    }

    // Query
    query := `
        {
            hello(foo:{key:"blah"})
        }
    `
    params := graphql.Params{Schema: schema, RequestString: query}
    r := graphql.Do(params)
    if len(r.Errors) > 0 {
        log.Fatalf("failed to execute graphql operation, errors: %+v", r.Errors)
    }
    rJSON, _ := json.Marshal(r)
    fmt.Printf("%s \n", rJSON) // {“data”:{“hello”:”world”}}
}
like image 177
R Menke Avatar answered Sep 28 '22 03:09

R Menke