graphql-go / graphql

An implementation of GraphQL for Go / Golang
MIT License
9.93k stars 840 forks source link

`DefaultResolveFn` does not work as expected with `map[K]V` for `K` that has string as the underlying type #700

Open bkrukowski opened 1 month ago

bkrukowski commented 1 month ago

Issue

DefaultResolveFn works properly for the following maps:

type MyMap map[string]any

but when we change the map key:

type MyKey string

type MyMap map[MyKey]any

it returns the following errors:

reflect.Value.MapIndex: value of type string is not assignable to type .*

Example:

Error

2009/11/10 23:00:00 failed to execute graphql operation, errors: [reflect.Value.MapIndex: value of type string is not assignable to type main.TranslationKey reflect.Value.MapIndex: value of type string is not assignable to type main.TranslationKey]

Code

package main

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

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

type TranslationKey string

type Translation map[TranslationKey]string

func main() {
    // Schema
    fields := graphql.Fields{
        "hello": &graphql.Field{
            Type: graphql.NewObject(graphql.ObjectConfig{
                Name: "Translation",
                Fields: graphql.Fields{
                    "en": &graphql.Field{
                        Type: graphql.String,
                    },
                    "fr": &graphql.Field{
                        Type: graphql.String,
                    },
                },
            }),
            Resolve: func(p graphql.ResolveParams) (interface{}, error) {
                return Translation{
                    "en": "hello",
                    "fr": "bonjour",
                }, 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 {
                en
                fr
            }
        }
    `
    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)
}

https://go.dev/play/p/giPGGUxKht8

Solution

The following PR solves that problem, but I believe it's been wrongly closed.

https://github.com/graphql-go/graphql/pull/697

Please take a look at the deeper explanation in the comment https://github.com/graphql-go/graphql/pull/697#issuecomment-2385949145

bkrukowski commented 1 month ago

@chris-ramon I hope this description clarifies your doubts

chris-ramon commented 1 month ago

ok thanks for the details, I'll give it a look.