gqlgen
gqlgen copied to clipboard
Extract result from parent resolver in the downstream resolver chains
What happened?
With following graphql schema:
type Base64Gif {
encoding: String!
}
type Content {
video_url: String!
gif: Base64Gif
}
type Metadata {
content: Content
start_time_sec: String!
}
type Query {
search(query: String!): [Metadata!]!
}
The resolvers are as below:
// Search is the resolver for the search field.
func (r *queryResolver) Search(ctx context.Context, query string) ([]*model.Metadata, error) {
...
}
// Content is the resolver for the content field.
func (r *metadataResolver) Content(ctx context.Context, obj *model.Metadata) (*model.Content, error) {
...
}
// Gif is the resolver for the gif field.
func (r *contentResolver) Gif(ctx context.Context, obj *model.Content) (*model.Base64Gif, error) {
// How do I access `start_time_sec` field which is present in the grandparent chain ?
}
versions
-
go run github.com/99designs/gqlgen version
? v0.17.36 -
go version
? go1.21.0 linux/amd64
It's tricky, but possible. Try this in your resolver Gif
:
func (r *contentResolver) Gif(ctx context.Context, obj *model.Content) (*model.Base64Gif, error) {
opCtx := graphql.GetFieldContext(ctx)
var indent int
for parent := opCtx.Parent; parent != nil; parent = parent.Parent {
fmt.Printf("%sparent %v\n", strings.Repeat(" ", indent), parent.Result)
indent += 1
}
}
You'll see what you need to do.
@geertjanvdk Is there a chance that parent.Result
returns all results not just from its immediate ancestor in the parent chain but also that ancestor’s siblings?
Since there is 1-1 relationship between Metadata
and Content
, I was trying to figure out how to get the corresponding start_time_sec
(Metadata) for which the Content
chain node was created subsequently in resolver chain. An implementation I came up with was similar to what you’ve proposed, however it didn’t work for me because of aforementioned combined results issue.
(moderators: this turns in a discussion; might be good to move this)
I am not sure I am grasping your need; maybe you need redo the schema? I can only give you tip on getting the parent(s) :)
I my case, I need to generate an id
for things that don't have one, based on the parent's ID. I do this like this:
var hg *MyThing
var ok bool
for p := graphql.GetFieldContext(ctx).Parent; ; p = p.Parent {
hg, ok = p.Result.(*MyThing)
if ok {
break
}
}
if hg == nil {
return "", fmt.Errorf("failing to get parent")
}
return hg.ID + ":" + string(obj.SomethingUnique), nil