Hi,
I have a simple mutation. It takes a couple of arguments (2 strings and 1 List of strings). I'm having trouble correctly unmarshalling the string. Is there a recommended approach to this - I can't find any other examples.
Here is the mutation:
var rootMutation = graphql.NewObject(graphql.ObjectConfig{
Name: "RootMutation",
Fields: graphql.Fields{
"WriteBook": &graphql.Field{
Type: bookType, // the return type for this field
Description: "Execute a new command - this creates a new command record",
Args: graphql.FieldConfigArgument{
"name": &graphql.ArgumentConfig{
Type: graphql.String,
},
"author": &graphql.ArgumentConfig{
Type: graphql.String,
},
"editions": &graphql.ArgumentConfig{
Type: graphql.NewList(graphql.String),
},
},
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
log.Printf("ARGS:", p.Args)
name, _ := p.Args["name"].(string)
log.Printf("Name: %s", name)
author, _ := p.Args["author"].(string)
log.Printf("Author: %s", author)
editions, _ := p.Args["editions"].([]string)
log.Printf("Editions: %s", editions)
book := Book{
Name: name,
Author: author,
}
database[name] = book
return book, nil
},
},
},
})
If I make the following request:
curl -XPOST http://localhost:8080/graphql -H 'Content-Type: application/json' -d \
'{
"query": "mutation CreateNewBook($name:String,$author:String,$editions:[String]){WriteBook(name:$name,author:$author,editions:$editions){name author}}",
"variables": "{\"name\": \"War and Peace\", \"author\": \"Some Guy\", \"editions\": [\"First\", \"Second\"]}"
}'
I can see the following logged:
ARGS:%!(EXTRA map[string]interface {}=map[editions:[First Second] name:War and Peace author:Some Guy])
Name: War and Peace
Author: Some Guy
Editions: []
I've attempted to cast the editions to []string. That just returns an empty array. If I try to cast to a string that also fails.
Any suggestions on how this should be handled?
In the end, I had to cast to []interface{} then iterate over that appending to a string list. There maybe a more efficient mechanism, but this works.
editions, _ := p.Args["editions"].([]interface{})
aString := make([]string, len(editions))
for _, v := range editions {
aString = append(aString, v.(string))
}
Is there a better way to do it?
In the end, I had to cast to []interface{} then iterate over that appending to a string list. There maybe a more efficient mechanism, but this works.
editions, _ := p.Args["editions"].([]interface{}) aString := make([]string, len(editions)) for _, v := range editions { aString = append(aString, v.(string)) }
I think you are expanding your array with the append function after you initialized it with the correct length.
Let's pretend you you have the following "editions" ["A", "B", "C"]. With your code the string array aString will look like this ["", "", "", "A", "B", "C"].
I would suggest the following:
editions, _ := p.Args["editions"].([]interface{})
aString := make([]string, len(editions))
for i, v := range editions {
aString[i] = v.(string) // use the index here
}
You can just assign the values to the positions in the array.
Most helpful comment
In the end, I had to cast to []interface{} then iterate over that appending to a string list. There maybe a more efficient mechanism, but this works.