graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.86k stars 838 forks source link

Parse error - Syntax Error GraphQL (57:49) Unexpected Name "null" #612

Open StarpTech opened 3 years ago

StarpTech commented 3 years ago

I faced this error during the benchmark of GraphQL parsers in the wild.

Query: https://github.com/StarpTech/graphql-parser-bench/blob/main/kitchen-sink.graphql Code: https://github.com/StarpTech/graphql-parser-bench/tree/main/go-graphql

2021/08/15 11:19:12 Syntax Error GraphQL (57:49) Unexpected Name "null"

56: {
57:   unnamed(truthy: true, falsey: false, nullish: null),
                                                    ^
58:   query
chrisfrank commented 7 months ago

I ran into this issue today when trying to write a mutation that allows clearing a nullable field. Here's an inline example that reproduces the problem. If a PR would be welcome, I'd be happy to try to open one with a fix. I think we can also work around this by agreeing on some sentinel value to treat as null, if that's what you'd advise. Thanks!

package main

import (
    "fmt"
    "log"

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

func main() {
    var config graphql.SchemaConfig
    config.Query = graphql.NewObject(graphql.ObjectConfig{
        Name:   "Query",
        Fields: graphql.Fields{},
    })
    config.Mutation = graphql.NewObject(graphql.ObjectConfig{
        Name: "Mutation",
        Fields: graphql.Fields{
            "put": &graphql.Field{
                Args: graphql.FieldConfigArgument{
                    "value": &graphql.ArgumentConfig{
                        Type: graphql.String,
                    },
                },
                Type: graphql.NewObject(graphql.ObjectConfig{
                    Name: "result",
                    Fields: graphql.Fields{
                        "value": &graphql.Field{Type: graphql.String},
                    },
                }),
                Resolve: func(p graphql.ResolveParams) (any, error) {
                    val := p.Args["value"]
                    return fmt.Sprintf("%v", val), nil
                },
            },
        },
    })
    schema, _ := graphql.NewSchema(config)

    for _, request := range []string{
        `mutation { put(value: "hello"){ value } }`,
        `mutation { put(value: ""){ value } }`,
        `mutation { put(value: null ){ value } }`,
    } {
        result := graphql.Do(graphql.Params{
            Schema:        schema,
            RequestString: request,
        })
        if result.HasErrors() {
            log.Fatalf("query %s has errors %v", request, result.Errors)
        }
    }
}