From 3bbc2a342fc7a0839b25e26ebd0aa25d7f498dac Mon Sep 17 00:00:00 2001 From: Daniel Vladco Date: Mon, 25 Oct 2021 00:17:45 +0300 Subject: [PATCH] feat: generate resolvers for inputs if fields are missing (#1404) Co-authored-by: daniel vladco Co-authored-by: davladco@cisco.com --- codegen/field.go | 10 ++++++++++ codegen/generated!.gotpl | 19 ++++++++++++++++++- codegen/input.gotpl | 28 +++++++++++++++++++++++----- 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/codegen/field.go b/codegen/field.go index 0833c1ebfba..245632aac02 100644 --- a/codegen/field.go +++ b/codegen/field.go @@ -461,6 +461,9 @@ func (f *Field) GoNameUnexported() string { } func (f *Field) ShortInvocation() string { + if f.Object.Kind == ast.InputObject { + return fmt.Sprintf("%s().%s(ctx, &it, data)", strings.Title(f.Object.Definition.Name), f.GoFieldName) + } return fmt.Sprintf("%s().%s(%s)", strings.Title(f.Object.Definition.Name), f.GoFieldName, f.CallArgs()) } @@ -481,6 +484,13 @@ func (f *Field) ResolverType() string { } func (f *Field) ShortResolverDeclaration() string { + if f.Object.Kind == ast.InputObject { + return fmt.Sprintf("(ctx context.Context, obj %s, data %s) error", + templates.CurrentImports.LookupType(f.Object.Reference()), + templates.CurrentImports.LookupType(f.TypeReference.GO), + ) + } + res := "(ctx context.Context" if !f.Object.Root { diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index e72fdd08bca..bf59daccef9 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -36,7 +36,12 @@ {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver {{ end }} {{- end }} - } + {{- range $object := .Inputs -}} + {{ if $object.HasResolvers -}} + {{ucFirst $object.Name}}() {{ucFirst $object.Name}}Resolver + {{ end }} +{{- end }} +} type DirectiveRoot struct { {{ range $directive := .Directives }} @@ -72,6 +77,18 @@ {{- end }} {{- end }} +{{ range $object := .Inputs -}} + {{ if $object.HasResolvers }} + type {{$object.Name}}Resolver interface { + {{ range $field := $object.Fields -}} + {{- if $field.IsResolver }} + {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }} + {{- end }} + {{ end }} + } + {{- end }} +{{- end }} + {{ if eq .Config.Exec.Layout "single-file" }} type executableSchema struct { resolvers ResolverRoot diff --git a/codegen/input.gotpl b/codegen/input.gotpl index 64681b61da3..5694bcd613c 100644 --- a/codegen/input.gotpl +++ b/codegen/input.gotpl @@ -29,20 +29,38 @@ return it, graphql.ErrorOnPath(ctx, err) } if data, ok := tmp.({{ $field.TypeReference.GO | ref }}) ; ok { - it.{{$field.GoFieldName}} = data + {{- if $field.IsResolver }} + if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { + return it, err + } + {{- else }} + it.{{$field.GoFieldName}} = data + {{- end }} {{- if $field.TypeReference.IsNilable }} + {{- if not $field.IsResolver }} } else if tmp == nil { it.{{$field.GoFieldName}} = nil + {{- end }} {{- end }} } else { err := fmt.Errorf(`unexpected type %T from directive, should be {{ $field.TypeReference.GO }}`, tmp) return it, graphql.ErrorOnPath(ctx, err) } {{- else }} - it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) - if err != nil { - return it, err - } + {{- if $field.IsResolver }} + data, err := ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) + if err != nil { + return it, err + } + if err = ec.resolvers.{{ $field.ShortInvocation }}; err != nil { + return it, err + } + {{- else }} + it.{{$field.GoFieldName}}, err = ec.{{ $field.TypeReference.UnmarshalFunc }}(ctx, v) + if err != nil { + return it, err + } + {{- end }} {{- end }} {{- end }} }