3

After generating the code using GqlGen there are some field resolvers method that has been created. I need to access the query input param in the field resolver but I'm not sure how to access it. Do I need to get these values from context? Or is there any other way?

Query Resolver:

func (r *queryResolver) Main(ctx context.Context, device string) (*models.Main, error) {
...
}

Field Resolver:

// Version is the resolver for the version field.
func (r *mainResolver) Version(ctx context.Context, obj *models.Main) (*models.Version, error) {
        // I NEED TO ACCESS device param here which is passed in Main method
    panic(fmt.Errorf("not implemented: Version - version"))
}

Thanks,

Shashank Sachan
  • 520
  • 1
  • 8
  • 20

1 Answers1

2

I think you can find the arguments in the FieldContext of the parent resolver. You can get it with graphql.GetFieldContext like this:

// Version is the resolver for the version field.
func (r *mainResolver) Version(ctx context.Context, obj *models.Main) (*models.Version, error) {
    device := graphql.GetFieldContext(ctx).Parent.Args["device"].(string)
    // ...
}

The field Args is a map[string]interface{}, so you access the arguments by name and then type-assert them to what they're supposed to be.

If the resolver is nested several levels, you can write a function that walks up the context chain until it finds the ancestor that has the value. With Go 1.18+ generics, the function can be reused for any value type, using a pattern similar to json.Unmarshal:

func FindGqlArgument[T any](ctx context.Context, key string, dst *T) {
    if dst == nil {
        panic("nil destination value")
    }
    for fc := graphql.GetFieldContext(ctx); fc != nil; fc = fc.Parent {
        v, ok := fc.Args[key]
        if ok {
            *dst = v.(T)
        }
    }
    // optionally handle failure state here
}

And use it as:

func (r *deeplyNestedResolver) Version(ctx context.Context, obj *models.Main) (*models.Version, error) {
    var device string 
    FindGqlArgument(ctx, "device", &device)
}

If that doesn't work, try also with graphql.GetOperationContext, which is basically undocumented... (credit to @Shashank Sachan)

graphql.GetOperationContext(ctx).Variables["device"].(string)
blackgreen
  • 34,072
  • 23
  • 111
  • 129