I'm trying to write a resolver that not only returns fields, but modifies the context, but I can't quite figure out how to do this.
Example:
// ResolveAllResources will process an allResources request
func ResolveAllResources(p graphql.ResolveParams) (interface{}, error) {
result := map[string]interface{}{
"totalCount": 1,
"pageInfo": dummyPageInfo,
"edges": []map[string]interface{}{},
"nodes": []map[string]interface{}{},
"groups": map[string]interface{}{},
}
ctx := context.WithValue(p.Context, "query", map[string]string{"myQuery": "foo"})
return result, nil
}
I can't see a way to stuff the new context in the request/response from here so that child resolvers can access it.
I'm used to doing this sort of thing in the Lacinia library from Clojure:
(defn resolve-resources-connection
[{:keys [query] :as context}
args parent]
(-> {:pageInfo dummy-page-info
:nodes []
:edges []
:groups {}}
(with-context (assoc context :query (build-query (:query context) nil args)))))
Hi @robdaemon, thanks a lot for using the lib and reaching us for a question.
Context is meant to be use as per-request and down to the stack. For example the current user logged in.
To pass arbitrary data from top resolvers to children resolvers, we can use the optional field RootValue.
I went ahead and wrote a small working example based on the snippet you shared:
package main
import (
"fmt"
"log"
"github.com/graphql-go/graphql"
)
var EdgeType = graphql.NewObject(graphql.ObjectConfig{
Name: "Edge",
Fields: graphql.Fields{
"node": &graphql.Field{
Type: graphql.String,
Resolve: func(p graphql.ResolveParams) (interface{}, error) {
rootValue := p.Info.RootValue.(map[string]interface{})
fmt.Printf("[node] rootValue: %+v\n", rootValue)
return nil, nil
},
},
},
})
func ResolveAllResources(p graphql.ResolveParams) (interface{}, error) {
rootValue := p.Info.RootValue.(map[string]interface{})
rootValue["query"] = map[string]string{"myQuery": "foo"}
fmt.Printf("[edge] rootValue: %+v\n", rootValue)
result := []string{"node1"}
return result, nil
}
func main() {
schema, err := graphql.NewSchema(graphql.SchemaConfig{
Query: graphql.NewObject(graphql.ObjectConfig{
Name: "Query",
Fields: graphql.Fields{
"edges": &graphql.Field{
Type: graphql.NewList(EdgeType),
Resolve: ResolveAllResources,
},
},
}),
})
if err != nil {
log.Fatal(err)
}
rootObject := make(map[string]interface{})
graphql.Do(graphql.Params{
Schema: schema,
RequestString: "{ edges { node } }",
RootObject: rootObject,
})
}
(issue-345)-> go run main.go
[edge] rootValue: map[query:map[myQuery:foo]]
[node] rootValue: map[query:map[myQuery:foo]]
Oh, great! Thank you. This works!
Since I expect to use this a lot in my project, I just added a simple helper function to my package:
func getRootValue(p graphql.ResolveParams) map[string]interface{} {
return p.Info.RootValue.(map[string]interface{})
}
Most helpful comment
Oh, great! Thank you. This works!
Since I expect to use this a lot in my project, I just added a simple helper function to my package: