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)