In a directive func, how do I get the name of its input field?
input ClientInput {
first_name: String! @required
...
}
func(ctx context.Context, obj interface{}, next graphql.Resolver) (interface{}, error) {
// How do I get "first_name" from here?
}
I have gone through anything that I could get from the variables I have. I have found that you get the attribute value through next(ctx) and you get the field name through graphql.GetFieldContext(ctx).Field.Name (but that would be the name of the mutation or where ever the input field has been used). I have found no possibility to retrieve that value.
Did you find a way of doing this?
I've been having to manually edit the generated file in order to pass the data through the "obj" field, but this is a hack
Did you find a way of doing this?
I've been having to manually edit the generated file in order to pass the data through the "obj" field, but this is a hack
No, I have not and I‘m still interested in a solution 😄
What temporarily worked for me was to dive into the generated code and manually inject the data
Under the respective directive, there is ... know what, lemme just post the generated code and what I modify so you can see for yourself
Old Code
func (ec *executionContext) _Query_timeline(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_timeline_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Timeline(rctx, args["topic"].(models.Topic), args["limit"].(*int64), args["olderThan"].(*string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAuthorisedTimelineQuery == nil {
return nil, errors.New("directive isAuthorisedTimelineQuery is not implemented")
}
return ec.directives.IsAuthorisedTimelineQuery(ctx, nil, directive0)
}
tmp, err := directive1(rctx)
if err != nil {
return nil, err
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*models.TimelineQuery); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/Zero-Q-Ltd/2bonge-back/models.TimelineQuery`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*models.TimelineQuery)
fc.Result = res
return ec.marshalNTimelineQuery2ᚖgithubᚗcomᚋZeroᚑQᚑLtdᚋ2bongeᚑbackᚋmodelsᚐTimelineQuery(ctx, field.Selections, res)
}
Modified code:
func (ec *executionContext) _Query_timeline(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = graphql.Null
}
}()
fc := &graphql.FieldContext{
Object: "Query",
Field: field,
Args: nil,
IsMethod: true,
}
ctx = graphql.WithFieldContext(ctx, fc)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_timeline_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
fc.Args = args
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Timeline(rctx, args["topic"].(models.Topic), args["limit"].(*int64), args["olderThan"].(*string))
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAuthorisedTimelineQuery == nil {
return nil, errors.New("directive isAuthorisedTimelineQuery is not implemented")
}
return ec.directives.IsAuthorisedTimelineQuery(ctx, args["params"].(models.TimelineQueryParams), directive0) // <---- THIS LINE HERE IS DEAFULT NIL
}
tmp, err := directive1(rctx)
if err != nil {
return nil, err
}
if tmp == nil {
return nil, nil
}
if data, ok := tmp.(*models.TimelineQuery); ok {
return data, nil
}
return nil, fmt.Errorf(`unexpected type %T from directive, should be *github.com/Zero-Q-Ltd/2bonge-back/models.TimelineQuery`, tmp)
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
return graphql.Null
}
res := resTmp.(*models.TimelineQuery)
fc.Result = res
return ec.marshalNTimelineQuery2ᚖgithubᚗcomᚋZeroᚑQᚑLtdᚋ2bongeᚑbackᚋmodelsᚐTimelineQuery(ctx, field.Selections, res)
}
This ONLY works if your directive is of type FIELD_DEFINITION, although I'm sure a similar "hack" can be found for other types
Also note that this seems like a known issue according to this documentation, although I think a better job can be done
Perfect! Thank you very much for sharing. Editing the generated code is not an option for me, but this looks like an easy pull request to me.
Actually, turns out this was already implemented, but maybe not properly documented, as I came across it by mistake in this comment by @vektah
Please take a look, and possibly close this issue or change the title to one that requests better documentation
using graphql.GetFieldContext(ctx).Args will give you the correct variables
Hello @kisinga , thanks for reaching back.
@vektah 's suggestion I think was graphql.GetFieldContext(ctx).Field.Name, which will give me createIngredient, which is the name of my mutation method.
You suggested graphql.GetFieldContext(ctx).Args. This will always give me an empty map map[].
Hello @kisinga , thanks for reaching back.
@vektah 's suggestion I think was
graphql.GetFieldContext(ctx).Field.Name, which will give mecreateIngredient, which is the name of my mutation method.You suggested
graphql.GetFieldContext(ctx).Args. This will always give me an empty mapmap[].
I have used the same and it yields a map of the values
Have you tried it?
Of course I did. At least that is what I get on log.Println.
My query looks like this btw:
mutation {
createIngredient(input:{
name: "", // this has the @required directive
...
}
}
Hm okay yeah that's weird. I have noted your contact, you may delete it. I'm currently working on a different task, so I might not get in touch with you today already. Thank you very much❣️
You can access the field name with graphql.GetPathContext(ctx).Field
That's it!!! Thank you @MichalZalecki
Most helpful comment
You can access the field name with
graphql.GetPathContext(ctx).Field