diff --git a/codegen/config.go b/codegen/config.go index 95b984027cc..0b6f98da435 100644 --- a/codegen/config.go +++ b/codegen/config.go @@ -78,7 +78,8 @@ type TypeMapEntry struct { } type TypeMapField struct { - Resolver bool `yaml:"resolver"` + Resolver bool `yaml:"resolver"` + FieldName string `yaml:"fieldName"` } func (c *PackageConfig) normalize() error { diff --git a/codegen/input_build.go b/codegen/input_build.go index 6dd58d4a3a1..c333201522d 100644 --- a/codegen/input_build.go +++ b/codegen/input_build.go @@ -16,7 +16,7 @@ func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, impo for _, typ := range cfg.schema.Types { switch typ.Kind { case ast.InputObject: - input, err := buildInput(namedTypes, typ) + input, err := cfg.buildInput(namedTypes, typ) if err != nil { return nil, err } @@ -44,8 +44,9 @@ func (cfg *Config) buildInputs(namedTypes NamedTypes, prog *loader.Program, impo return inputs, nil } -func buildInput(types NamedTypes, typ *ast.Definition) (*Object, error) { +func (cfg *Config) buildInput(types NamedTypes, typ *ast.Definition) (*Object, error) { obj := &Object{NamedType: types[typ.Name]} + typeEntry, entryExists := cfg.Models[typ.Name] for _, field := range typ.Fields { newField := Field{ @@ -54,6 +55,12 @@ func buildInput(types NamedTypes, typ *ast.Definition) (*Object, error) { Object: obj, } + if entryExists { + if typeField, ok := typeEntry.Fields[field.Name]; ok { + newField.GoFieldName = typeField.FieldName + } + } + if field.DefaultValue != nil { var err error newField.Default, err = field.DefaultValue.Value(nil) diff --git a/codegen/model.go b/codegen/model.go index 164a04d5b50..7b46a318c2b 100644 --- a/codegen/model.go +++ b/codegen/model.go @@ -8,8 +8,8 @@ type Model struct { type ModelField struct { *Type - GQLName string - GoVarName string - GoFKName string - GoFKType string + GQLName string + GoFieldName string + GoFKName string + GoFKType string } diff --git a/codegen/models_build.go b/codegen/models_build.go index 3b590a36d4f..fa01a03a029 100644 --- a/codegen/models_build.go +++ b/codegen/models_build.go @@ -24,7 +24,7 @@ func (cfg *Config) buildModels(types NamedTypes, prog *loader.Program, imports * } model = cfg.obj2Model(obj) case ast.InputObject: - obj, err := buildInput(types, typ) + obj, err := cfg.buildInput(types, typ) if err != nil { return nil, err } @@ -65,10 +65,14 @@ func (cfg *Config) obj2Model(obj *Object) Model { field := &obj.Fields[i] mf := ModelField{Type: field.Type, GQLName: field.GQLName} - mf.GoVarName = ucFirst(field.GQLName) - if mf.IsScalar { - if mf.GoVarName == "Id" { - mf.GoVarName = "ID" + if field.GoFieldName != "" { + mf.GoFieldName = field.GoFieldName + } else { + mf.GoFieldName = ucFirst(field.GQLName) + if mf.IsScalar { + if mf.GoFieldName == "Id" { + mf.GoFieldName = "ID" + } } } diff --git a/codegen/object.go b/codegen/object.go index d38d5e06d10..83ed7bad938 100644 --- a/codegen/object.go +++ b/codegen/object.go @@ -9,6 +9,14 @@ import ( "unicode" ) +type GoFieldType int + +const ( + GoFieldUndefined GoFieldType = iota + GoFieldMethod + GoFieldVariable +) + type Object struct { *NamedType @@ -23,14 +31,15 @@ type Object struct { type Field struct { *Type - GQLName string // The name of the field in graphql - GoMethodName string // The name of the method in go, if any - GoVarName string // The name of the var in go, if any - Args []FieldArgument // A list of arguments to be passed to this field - ForceResolver bool // Should be emit Resolver method - NoErr bool // If this is bound to a go method, does that method have an error as the second argument - Object *Object // A link back to the parent object - Default interface{} // The default value + GQLName string // The name of the field in graphql + GoFieldType GoFieldType // The field type in go, if any + GoReceiverName string // The name of method & var receiver in go, if any + GoFieldName string // The name of the method or var in go, if any + Args []FieldArgument // A list of arguments to be passed to this field + ForceResolver bool // Should be emit Resolver method + NoErr bool // If this is bound to a go method, does that method have an error as the second argument + Object *Object // A link back to the parent object + Default interface{} // The default value } type FieldArgument struct { @@ -62,7 +71,15 @@ func (o *Object) HasResolvers() bool { } func (f *Field) IsResolver() bool { - return f.ForceResolver || f.GoMethodName == "" && f.GoVarName == "" + return f.ForceResolver || f.GoFieldName == "" +} + +func (f *Field) IsMethod() bool { + return f.GoFieldType == GoFieldMethod +} + +func (f *Field) IsVariable() bool { + return f.GoFieldType == GoFieldVariable } func (f *Field) IsConcurrent() bool { @@ -120,7 +137,7 @@ func (f *Field) ResolverDeclaration() string { func (f *Field) CallArgs() string { var args []string - if f.GoMethodName == "" { + if f.IsResolver() { args = append(args, "ctx") if !f.Object.Root { diff --git a/codegen/object_build.go b/codegen/object_build.go index 9d9b46364b8..3dfa7fd1567 100644 --- a/codegen/object_build.go +++ b/codegen/object_build.go @@ -107,20 +107,24 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I for _, field := range typ.Fields { if typ == cfg.schema.Query && field.Name == "__type" { obj.Fields = append(obj.Fields, Field{ - Type: &Type{types["__Schema"], []string{modPtr}, nil}, - GQLName: "__schema", - NoErr: true, - GoMethodName: "ec.introspectSchema", - Object: obj, + Type: &Type{types["__Schema"], []string{modPtr}, nil}, + GQLName: "__schema", + NoErr: true, + GoFieldType: GoFieldMethod, + GoReceiverName: "ec", + GoFieldName: "introspectSchema", + Object: obj, }) continue } if typ == cfg.schema.Query && field.Name == "__schema" { obj.Fields = append(obj.Fields, Field{ - Type: &Type{types["__Type"], []string{modPtr}, nil}, - GQLName: "__type", - NoErr: true, - GoMethodName: "ec.introspectType", + Type: &Type{types["__Type"], []string{modPtr}, nil}, + GQLName: "__type", + NoErr: true, + GoFieldType: GoFieldMethod, + GoReceiverName: "ec", + GoFieldName: "introspectType", Args: []FieldArgument{ {GQLName: "name", Type: &Type{types["String"], []string{}, nil}, Object: &Object{}}, }, @@ -130,8 +134,10 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I } var forceResolver bool + var goName string if entryExists { if typeField, ok := typeEntry.Fields[field.Name]; ok { + goName = typeField.FieldName forceResolver = typeField.Resolver } } @@ -165,6 +171,7 @@ func (cfg *Config) buildObject(types NamedTypes, typ *ast.Definition, imports *I Type: types.getType(field.Type), Args: args, Object: obj, + GoFieldName: goName, ForceResolver: forceResolver, }) } diff --git a/codegen/templates/data.go b/codegen/templates/data.go index 6c229f8045f..917f31626d7 100644 --- a/codegen/templates/data.go +++ b/codegen/templates/data.go @@ -2,11 +2,11 @@ package templates var data = map[string]string{ "args.gotpl": "\t{{- if . }}args := map[string]interface{}{} {{end}}\n\t{{- range $i, $arg := . }}\n\t\tvar arg{{$i}} {{$arg.Signature }}\n\t\tif tmp, ok := field.Args[{{$arg.GQLName|quote}}]; ok {\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\t{{- if $arg.Object.Stream }}\n\t\t\t\t\treturn nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn graphql.Null\n\t\t\t\t{{- end }}\n\t\t\t}\n\t\t} {{ if $arg.Default }} else {\n\t\t\tvar tmp interface{} = {{ $arg.Default | dump }}\n\t\t\tvar err error\n\t\t\t{{$arg.Unmarshal (print \"arg\" $i) \"tmp\" }}\n\t\t\tif err != nil {\n\t\t\t\tec.Error(ctx, err)\n\t\t\t\t{{- if $arg.Object.Stream }}\n\t\t\t\t\treturn nil\n\t\t\t\t{{- else }}\n\t\t\t\t\treturn graphql.Null\n\t\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\t\t{{end }}\n\t\targs[{{$arg.GQLName|quote}}] = arg{{$i}}\n\t{{- end -}}\n", - "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\n\t\t{{- if $field.IsConcurrent }}\n\t\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\t\tField: field,\n\t\t\t})\n\t\t\treturn graphql.Defer(func() (ret graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tuserErr := ec.Recover(ctx, r)\n\t\t\t\t\t\tec.Error(ctx, userErr)\n\t\t\t\t\t\tret = graphql.Null\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t{{ else }}\n\t\t\trctx := graphql.GetResolverContext(ctx)\n\t\t\trctx.Object = {{$object.GQLType|quote}}\n\t\t\trctx.Args = {{if $field.Args }}args{{else}}nil{{end}}\n\t\t\trctx.Field = field\n\t\t\trctx.PushField(field.Alias)\n\t\t\tdefer rctx.Pop()\n\t\t{{- end }}\n\t\t\tresTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) {\n\t\t\t\t{{- if $field.IsResolver }}\n\t\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t\t{{- else if $field.GoVarName }}\n\t\t\t\t\treturn obj.{{$field.GoVarName}}, nil\n\t\t\t\t{{- else if $field.GoMethodName }}\n\t\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\t\treturn {{$field.GoMethodName}}({{ $field.CallArgs }}), nil\n\t\t\t\t\t{{- else }}\n\t\t\t\t\t\treturn {{$field.GoMethodName}}({{ $field.CallArgs }})\n\t\t\t\t\t{{- end }}\n\t\t\t\t{{- end }}\n\t\t\t})\n\t\t\tif resTmp == nil {\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t\tres := resTmp.({{$field.Signature}})\n\t\t\t{{ $field.WriteJson }}\n\t\t{{- if $field.IsConcurrent }}\n\t\t\t})\n\t\t{{- end }}\n\t}\n{{ end }}\n", + "field.gotpl": "{{ $field := . }}\n{{ $object := $field.Object }}\n\n{{- if $object.Stream }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})\n\t\tresults, err := ec.resolvers.{{ $field.ShortInvocation }}\n\t\tif err != nil {\n\t\t\tec.Error(ctx, err)\n\t\t\treturn nil\n\t\t}\n\t\treturn func() graphql.Marshaler {\n\t\t\tres, ok := <-results\n\t\t\tif !ok {\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar out graphql.OrderedMap\n\t\t\tout.Add(field.Alias, func() graphql.Marshaler { {{ $field.WriteJson }} }())\n\t\t\treturn &out\n\t\t}\n\t}\n{{ else }}\n\tfunc (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {\n\t\t{{- template \"args.gotpl\" $field.Args }}\n\n\t\t{{- if $field.IsConcurrent }}\n\t\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\t\tObject: {{$object.GQLType|quote}},\n\t\t\t\tArgs: {{if $field.Args }}args{{else}}nil{{end}},\n\t\t\t\tField: field,\n\t\t\t})\n\t\t\treturn graphql.Defer(func() (ret graphql.Marshaler) {\n\t\t\t\tdefer func() {\n\t\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\t\tuserErr := ec.Recover(ctx, r)\n\t\t\t\t\t\tec.Error(ctx, userErr)\n\t\t\t\t\t\tret = graphql.Null\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t{{ else }}\n\t\t\trctx := graphql.GetResolverContext(ctx)\n\t\t\trctx.Object = {{$object.GQLType|quote}}\n\t\t\trctx.Args = {{if $field.Args }}args{{else}}nil{{end}}\n\t\t\trctx.Field = field\n\t\t\trctx.PushField(field.Alias)\n\t\t\tdefer rctx.Pop()\n\t\t{{- end }}\n\t\t\tresTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) {\n\t\t\t\t{{- if $field.IsResolver }}\n\t\t\t\t\treturn ec.resolvers.{{ $field.ShortInvocation }}\n\t\t\t\t{{- else if $field.IsMethod }}\n\t\t\t\t\t{{- if $field.NoErr }}\n\t\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil\n\t\t\t\t\t{{- else }}\n\t\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }})\n\t\t\t\t\t{{- end }}\n\t\t\t\t{{- else if $field.IsVariable }}\n\t\t\t\t\treturn {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil\n\t\t\t\t{{- end }}\n\t\t\t})\n\t\t\tif resTmp == nil {\n\t\t\t\treturn graphql.Null\n\t\t\t}\n\t\t\tres := resTmp.({{$field.Signature}})\n\t\t\t{{ $field.WriteJson }}\n\t\t{{- if $field.IsConcurrent }}\n\t\t\t})\n\t\t{{- end }}\n\t}\n{{ end }}\n", "generated.gotpl": "// Code generated by github.com/vektah/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.\nfunc NewExecutableSchema(cfg Config) graphql.ExecutableSchema {\n\treturn &executableSchema{\n\t\tresolvers: cfg.Resolvers,\n\t\tdirectives: cfg.Directives,\n\t}\n}\n\ntype Config struct {\n\tResolvers ResolverRoot\n\tDirectives DirectiveRoot\n}\n\ntype ResolverRoot interface {\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers -}}\n\t\t{{$object.GQLType}}() {{$object.GQLType}}Resolver\n\t{{ end }}\n{{- end }}\n}\n\ntype DirectiveRoot struct {\n{{ range $directive := .Directives }}\n\t{{$directive.Name|ucFirst}} graphql.FieldMiddleware\n{{ end }}\n}\n\n{{- range $object := .Objects -}}\n\t{{ if $object.HasResolvers }}\n\t\ttype {{$object.GQLType}}Resolver interface {\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{ $field.ShortResolverDeclaration }}\n\t\t{{ end }}\n\t\t}\n\t{{- end }}\n{{- end }}\n\ntype executableSchema struct {\n\tresolvers ResolverRoot\n\tdirectives DirectiveRoot\n}\n\nfunc (e *executableSchema) Schema() *ast.Schema {\n\treturn parsedSchema\n}\n\nfunc (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .QueryRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"queries are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {\n\t{{- if .MutationRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\tdata := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)\n\t\t\tvar buf bytes.Buffer\n\t\t\tdata.MarshalGQL(&buf)\n\t\t\treturn buf.Bytes()\n\t\t})\n\n\t\treturn &graphql.Response{\n\t\t\tData: buf,\n\t\t\tErrors: ec.Errors,\n\t\t}\n\t{{- else }}\n\t\treturn graphql.ErrorResponse(ctx, \"mutations are not supported\")\n\t{{- end }}\n}\n\nfunc (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {\n\t{{- if .SubscriptionRoot }}\n\t\tec := executionContext{graphql.GetRequestContext(ctx), e}\n\n\t\tnext := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)\n\t\tif ec.Errors != nil {\n\t\t\treturn graphql.OneShot(&graphql.Response{Data: []byte(\"null\"), Errors: ec.Errors})\n\t\t}\n\n\t\tvar buf bytes.Buffer\n\t\treturn func() *graphql.Response {\n\t\t\tbuf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {\n\t\t\t\tbuf.Reset()\n\t\t\t\tdata := next()\n\n\t\t\t\tif data == nil {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t\tdata.MarshalGQL(&buf)\n\t\t\t\treturn buf.Bytes()\n\t\t\t})\n\n\t\t\treturn &graphql.Response{\n\t\t\t\tData: buf,\n\t\t\t\tErrors: ec.Errors,\n\t\t\t}\n\t\t}\n\t{{- else }}\n\t\treturn graphql.OneShot(graphql.ErrorResponse(ctx, \"subscriptions are not supported\"))\n\t{{- end }}\n}\n\ntype executionContext struct {\n\t*graphql.RequestContext\n\t*executableSchema\n}\n\n{{- range $object := .Objects }}\n\t{{ template \"object.gotpl\" $object }}\n\n\t{{- range $field := $object.Fields }}\n\t\t{{ template \"field.gotpl\" $field }}\n\t{{ end }}\n{{- end}}\n\n{{- range $interface := .Interfaces }}\n\t{{ template \"interface.gotpl\" $interface }}\n{{- end }}\n\n{{- range $input := .Inputs }}\n\t{{ template \"input.gotpl\" $input }}\n{{- end }}\n\nfunc (ec *executionContext) FieldMiddleware(ctx context.Context, next graphql.Resolver) interface{} {\n\t{{- if .Directives }}\n\trctx := graphql.GetResolverContext(ctx)\n\tfor _, d := range rctx.Field.Definition.Directives {\n\t\tswitch d.Name {\n\t\t{{- range $directive := .Directives }}\n\t\tcase \"{{$directive.Name}}\":\n\t\t\tif ec.directives.{{$directive.Name|ucFirst}} != nil {\n\t\t\t\tn := next\n\t\t\t\tnext = func(ctx context.Context) (interface{}, error) {\n\t\t\t\t\treturn ec.directives.{{$directive.Name|ucFirst}}(ctx, n)\n\t\t\t\t}\n\t\t\t}\n\t\t{{- end }}\n\t\t}\n\t}\n\t{{- end }}\n\tres, err := ec.ResolverMiddleware(ctx, next)\n\tif err != nil {\n\t\tec.Error(ctx, err)\n\t\treturn nil\n\t}\n\treturn res\n}\n\nfunc (ec *executionContext) introspectSchema() *introspection.Schema {\n\treturn introspection.WrapSchema(parsedSchema)\n}\n\nfunc (ec *executionContext) introspectType(name string) *introspection.Type {\n\treturn introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name])\n}\n\nvar parsedSchema = gqlparser.MustLoadSchema(\n\t&ast.Source{Name: {{.SchemaFilename|quote}}, Input: {{.SchemaRaw|rawQuote}}},\n)\n", - "input.gotpl": "\t{{- if .IsMarshaled }}\n\tfunc Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {\n\t\tvar it {{.FullName}}\n\t\tvar asMap = v.(map[string]interface{})\n\t\t{{ range $field := .Fields}}\n\t\t\t{{- if $field.Default}}\n\t\t\t\tif _, present := asMap[{{$field.GQLName|quote}}] ; !present {\n\t\t\t\t\tasMap[{{$field.GQLName|quote}}] = {{ $field.Default | dump }}\n\t\t\t\t}\n\t\t\t{{- end}}\n\t\t{{- end }}\n\n\t\tfor k, v := range asMap {\n\t\t\tswitch k {\n\t\t\t{{- range $field := .Fields }}\n\t\t\tcase {{$field.GQLName|quote}}:\n\t\t\t\tvar err error\n\t\t\t\t{{ $field.Unmarshal (print \"it.\" $field.GoVarName) \"v\" }}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn it, err\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\n\t\treturn it, nil\n\t}\n\t{{- end }}\n", + "input.gotpl": "\t{{- if .IsMarshaled }}\n\tfunc Unmarshal{{ .GQLType }}(v interface{}) ({{.FullName}}, error) {\n\t\tvar it {{.FullName}}\n\t\tvar asMap = v.(map[string]interface{})\n\t\t{{ range $field := .Fields}}\n\t\t\t{{- if $field.Default}}\n\t\t\t\tif _, present := asMap[{{$field.GQLName|quote}}] ; !present {\n\t\t\t\t\tasMap[{{$field.GQLName|quote}}] = {{ $field.Default | dump }}\n\t\t\t\t}\n\t\t\t{{- end}}\n\t\t{{- end }}\n\n\t\tfor k, v := range asMap {\n\t\t\tswitch k {\n\t\t\t{{- range $field := .Fields }}\n\t\t\tcase {{$field.GQLName|quote}}:\n\t\t\t\tvar err error\n\t\t\t\t{{ $field.Unmarshal (print \"it.\" $field.GoFieldName) \"v\" }}\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn it, err\n\t\t\t\t}\n\t\t\t{{- end }}\n\t\t\t}\n\t\t}\n\n\t\treturn it, nil\n\t}\n\t{{- end }}\n", "interface.gotpl": "{{- $interface := . }}\n\nfunc (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel ast.SelectionSet, obj *{{$interface.FullName}}) graphql.Marshaler {\n\tswitch obj := (*obj).(type) {\n\tcase nil:\n\t\treturn graphql.Null\n\t{{- range $implementor := $interface.Implementors }}\n\t\t{{- if $implementor.ValueReceiver }}\n\t\t\tcase {{$implementor.FullName}}:\n\t\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, &obj)\n\t\t{{- end}}\n\t\tcase *{{$implementor.FullName}}:\n\t\t\treturn ec._{{$implementor.GQLType}}(ctx, sel, obj)\n\t{{- end }}\n\tdefault:\n\t\tpanic(fmt.Errorf(\"unexpected type %T\", obj))\n\t}\n}\n", - "models.gotpl": "// Code generated by github.com/vektah/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n{{ range $model := .Models }}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- if $field.GoVarName }}\n\t\t\t\t\t{{ $field.GoVarName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\ttype {{.GoType}} string\n\tconst (\n\t{{ range $value := .Values -}}\n\t\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n", + "models.gotpl": "// Code generated by github.com/vektah/gqlgen, DO NOT EDIT.\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\n{{ range $model := .Models }}\n\t{{- if .IsInterface }}\n\t\ttype {{.GoType}} interface {}\n\t{{- else }}\n\t\ttype {{.GoType}} struct {\n\t\t\t{{- range $field := .Fields }}\n\t\t\t\t{{- if $field.GoFieldName }}\n\t\t\t\t\t{{ $field.GoFieldName }} {{$field.Signature}} `json:\"{{$field.GQLName}}\"`\n\t\t\t\t{{- else }}\n\t\t\t\t\t{{ $field.GoFKName }} {{$field.GoFKType}}\n\t\t\t\t{{- end }}\n\t\t\t{{- end }}\n\t\t}\n\t{{- end }}\n{{- end}}\n\n{{ range $enum := .Enums }}\n\ttype {{.GoType}} string\n\tconst (\n\t{{ range $value := .Values -}}\n\t\t{{with .Description}} {{.|prefixLines \"// \"}} {{end}}\n\t\t{{$enum.GoType}}{{ .Name|toCamel }} {{$enum.GoType}} = {{.Name|quote}}\n\t{{- end }}\n\t)\n\n\tfunc (e {{.GoType}}) IsValid() bool {\n\t\tswitch e {\n\t\tcase {{ range $index, $element := .Values}}{{if $index}},{{end}}{{ $enum.GoType }}{{ $element.Name|toCamel }}{{end}}:\n\t\t\treturn true\n\t\t}\n\t\treturn false\n\t}\n\n\tfunc (e {{.GoType}}) String() string {\n\t\treturn string(e)\n\t}\n\n\tfunc (e *{{.GoType}}) UnmarshalGQL(v interface{}) error {\n\t\tstr, ok := v.(string)\n\t\tif !ok {\n\t\t\treturn fmt.Errorf(\"enums must be strings\")\n\t\t}\n\n\t\t*e = {{.GoType}}(str)\n\t\tif !e.IsValid() {\n\t\t\treturn fmt.Errorf(\"%s is not a valid {{.GQLType}}\", str)\n\t\t}\n\t\treturn nil\n\t}\n\n\tfunc (e {{.GoType}}) MarshalGQL(w io.Writer) {\n\t\tfmt.Fprint(w, strconv.Quote(e.String()))\n\t}\n\n{{- end }}\n", "object.gotpl": "{{ $object := . }}\n\nvar {{ $object.GQLType|lcFirst}}Implementors = {{$object.Implementors}}\n\n// nolint: gocyclo, errcheck, gas, goconst\n{{- if .Stream }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\tObject: {{$object.GQLType|quote}},\n\t})\n\tif len(fields) != 1 {\n\t\tec.Errorf(ctx, \"must subscribe to exactly one stream\")\n\t\treturn nil\n\t}\n\n\tswitch fields[0].Name {\n\t{{- range $field := $object.Fields }}\n\tcase \"{{$field.GQLName}}\":\n\t\treturn ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, fields[0])\n\t{{- end }}\n\tdefault:\n\t\tpanic(\"unknown field \" + strconv.Quote(fields[0].Name))\n\t}\n}\n{{- else }}\nfunc (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel ast.SelectionSet{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {\n\tfields := graphql.CollectFields(ctx, sel, {{$object.GQLType|lcFirst}}Implementors)\n\t{{if $object.Root}}\n\t\tctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{\n\t\t\tObject: {{$object.GQLType|quote}},\n\t\t})\n\t{{end}}\n\tout := graphql.NewOrderedMap(len(fields))\n\tfor i, field := range fields {\n\t\tout.Keys[i] = field.Alias\n\n\t\tswitch field.Name {\n\t\tcase \"__typename\":\n\t\t\tout.Values[i] = graphql.MarshalString({{$object.GQLType|quote}})\n\t\t{{- range $field := $object.Fields }}\n\t\tcase \"{{$field.GQLName}}\":\n\t\t\tout.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, field{{if not $object.Root}}, obj{{end}})\n\t\t{{- end }}\n\t\tdefault:\n\t\t\tpanic(\"unknown field \" + strconv.Quote(field.Name))\n\t\t}\n\t}\n\n\treturn out\n}\n{{- end }}\n", "resolver.gotpl": "//go:generate gorunpkg github.com/vektah/gqlgen\n\npackage {{ .PackageName }}\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\ntype {{.ResolverType}} struct {}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\tfunc (r *{{$.ResolverType}}) {{$object.GQLType}}() {{ $object.ResolverInterface.FullName }} {\n\t\t\treturn &{{lcFirst $object.GQLType}}Resolver{r}\n\t\t}\n\t{{ end -}}\n{{ end }}\n\n{{ range $object := .Objects -}}\n\t{{- if $object.HasResolvers -}}\n\t\ttype {{lcFirst $object.GQLType}}Resolver struct { *Resolver }\n\n\t\t{{ range $field := $object.Fields -}}\n\t\t\t{{- if $field.IsResolver -}}\n\t\t\tfunc (r *{{lcFirst $object.GQLType}}Resolver) {{ $field.ShortResolverDeclaration }} {\n\t\t\t\tpanic(\"not implemented\")\n\t\t\t}\n\t\t\t{{ end -}}\n\t\t{{ end -}}\n\t{{ end -}}\n{{ end }}\n", "server.gotpl": "package main\n\nimport (\n{{- range $import := .Imports }}\n\t{{- $import.Write }}\n{{ end }}\n)\n\nconst defaultPort = \"8080\"\n\nfunc main() {\n\tport := os.Getenv(\"PORT\")\n\tif port == \"\" {\n\t\tport = defaultPort\n\t}\n\n\thttp.Handle(\"/\", handler.Playground(\"GraphQL playground\", \"/query\"))\n\thttp.Handle(\"/query\", handler.GraphQL({{.ExecPackageName}}.NewExecutableSchema({{.ExecPackageName}}.Config{Resolvers: &{{.ResolverPackageName}}.Resolver{}})))\n\n\tlog.Printf(\"connect to http://localhost:%s/ for GraphQL playground\", port)\n\tlog.Fatal(http.ListenAndServe(\":\" + port, nil))\n}\n", diff --git a/codegen/templates/field.gotpl b/codegen/templates/field.gotpl index 428a1df44fb..8e252adefaa 100644 --- a/codegen/templates/field.gotpl +++ b/codegen/templates/field.gotpl @@ -49,14 +49,14 @@ resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { {{- if $field.IsResolver }} return ec.resolvers.{{ $field.ShortInvocation }} - {{- else if $field.GoVarName }} - return obj.{{$field.GoVarName}}, nil - {{- else if $field.GoMethodName }} + {{- else if $field.IsMethod }} {{- if $field.NoErr }} - return {{$field.GoMethodName}}({{ $field.CallArgs }}), nil + return {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}), nil {{- else }} - return {{$field.GoMethodName}}({{ $field.CallArgs }}) + return {{$field.GoReceiverName}}.{{$field.GoFieldName}}({{ $field.CallArgs }}) {{- end }} + {{- else if $field.IsVariable }} + return {{$field.GoReceiverName}}.{{$field.GoFieldName}}, nil {{- end }} }) if resTmp == nil { diff --git a/codegen/templates/input.gotpl b/codegen/templates/input.gotpl index 6073daf4ee6..f543608df0c 100644 --- a/codegen/templates/input.gotpl +++ b/codegen/templates/input.gotpl @@ -15,7 +15,7 @@ {{- range $field := .Fields }} case {{$field.GQLName|quote}}: var err error - {{ $field.Unmarshal (print "it." $field.GoVarName) "v" }} + {{ $field.Unmarshal (print "it." $field.GoFieldName) "v" }} if err != nil { return it, err } diff --git a/codegen/templates/models.gotpl b/codegen/templates/models.gotpl index e66266a520b..ed9523059a6 100644 --- a/codegen/templates/models.gotpl +++ b/codegen/templates/models.gotpl @@ -14,8 +14,8 @@ import ( {{- else }} type {{.GoType}} struct { {{- range $field := .Fields }} - {{- if $field.GoVarName }} - {{ $field.GoVarName }} {{$field.Signature}} `json:"{{$field.GQLName}}"` + {{- if $field.GoFieldName }} + {{ $field.GoFieldName }} {{$field.Signature}} `json:"{{$field.GQLName}}"` {{- else }} {{ $field.GoFKName }} {{$field.GoFKType}} {{- end }} diff --git a/codegen/util.go b/codegen/util.go index 5c5bd5cf0e2..f1732ad1125 100644 --- a/codegen/util.go +++ b/codegen/util.go @@ -194,7 +194,11 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error { return fmt.Errorf("not a named type") } - method := findMethod(namedType, field.GQLName) + goName := field.GQLName + if field.GoFieldName != "" { + goName = field.GoFieldName + } + method := findMethod(namedType, goName) if method == nil { return fmt.Errorf("no method named %s", field.GQLName) } @@ -216,7 +220,9 @@ func bindMethod(imports *Imports, t types.Type, field *Field) error { } // success, args and return type match. Bind to method - field.GoMethodName = "obj." + method.Name() + field.GoFieldType = GoFieldMethod + field.GoReceiverName = "obj" + field.GoFieldName = method.Name() field.Args = newArgs return nil } @@ -227,7 +233,11 @@ func bindVar(imports *Imports, t types.Type, field *Field) error { return fmt.Errorf("not a struct") } - structField := findField(underlying, field.GQLName) + goName := field.GQLName + if field.GoFieldName != "" { + goName = field.GoFieldName + } + structField := findField(underlying, goName) if structField == nil { return fmt.Errorf("no field named %s", field.GQLName) } @@ -237,7 +247,9 @@ func bindVar(imports *Imports, t types.Type, field *Field) error { } // success, bind to var - field.GoVarName = structField.Name() + field.GoFieldType = GoFieldVariable + field.GoReceiverName = "obj" + field.GoFieldName = structField.Name() return nil } diff --git a/example/config/.gqlgen.yml b/example/config/.gqlgen.yml new file mode 100644 index 00000000000..6f7761f2cba --- /dev/null +++ b/example/config/.gqlgen.yml @@ -0,0 +1,28 @@ +# .gqlgen.yml example +# +# Refer to https://gqlgen.com/config/ +# for detailed .gqlgen.yml documentation. + +schema: schema.graphql +exec: + filename: generated.go +model: + filename: models_gen.go +resolver: + filename: resolver.go + type: Resolver + +models: + Todo: # Object + fields: + text: + fieldName: Description # Field + NewTodo: # Input + fields: + userId: + fieldName: UserID # Field + User: + model: github.com/vektah/gqlgen/example/config.User + fields: + name: + fieldName: FullName # Method diff --git a/example/config/generated.go b/example/config/generated.go new file mode 100644 index 00000000000..97665720f3d --- /dev/null +++ b/example/config/generated.go @@ -0,0 +1,1356 @@ +// Code generated by github.com/vektah/gqlgen, DO NOT EDIT. + +package config + +import ( + "bytes" + context "context" + strconv "strconv" + + graphql "github.com/vektah/gqlgen/graphql" + introspection "github.com/vektah/gqlgen/graphql/introspection" + gqlparser "github.com/vektah/gqlparser" + ast "github.com/vektah/gqlparser/ast" +) + +// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. +func NewExecutableSchema(cfg Config) graphql.ExecutableSchema { + return &executableSchema{ + resolvers: cfg.Resolvers, + directives: cfg.Directives, + } +} + +type Config struct { + Resolvers ResolverRoot + Directives DirectiveRoot +} + +type ResolverRoot interface { + Mutation() MutationResolver + Query() QueryResolver +} + +type DirectiveRoot struct { +} +type MutationResolver interface { + CreateTodo(ctx context.Context, input NewTodo) (Todo, error) +} +type QueryResolver interface { + Todos(ctx context.Context) ([]Todo, error) +} + +type executableSchema struct { + resolvers ResolverRoot + directives DirectiveRoot +} + +func (e *executableSchema) Schema() *ast.Schema { + return parsedSchema +} + +func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response { + ec := executionContext{graphql.GetRequestContext(ctx), e} + + buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte { + data := ec._Query(ctx, op.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + return buf.Bytes() + }) + + return &graphql.Response{ + Data: buf, + Errors: ec.Errors, + } +} + +func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response { + ec := executionContext{graphql.GetRequestContext(ctx), e} + + buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte { + data := ec._Mutation(ctx, op.SelectionSet) + var buf bytes.Buffer + data.MarshalGQL(&buf) + return buf.Bytes() + }) + + return &graphql.Response{ + Data: buf, + Errors: ec.Errors, + } +} + +func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response { + return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported")) +} + +type executionContext struct { + *graphql.RequestContext + *executableSchema +} + +var mutationImplementors = []string{"Mutation"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, mutationImplementors) + + ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ + Object: "Mutation", + }) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Mutation") + case "createTodo": + out.Values[i] = ec._Mutation_createTodo(ctx, field) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) _Mutation_createTodo(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + args := map[string]interface{}{} + var arg0 NewTodo + if tmp, ok := field.Args["input"]; ok { + var err error + arg0, err = UnmarshalNewTodo(tmp) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + } + args["input"] = arg0 + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Mutation" + rctx.Args = args + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.Mutation().CreateTodo(ctx, args["input"].(NewTodo)) + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(Todo) + return ec._Todo(ctx, field.Selections, &res) +} + +var queryImplementors = []string{"Query"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, queryImplementors) + + ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ + Object: "Query", + }) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Query") + case "todos": + out.Values[i] = ec._Query_todos(ctx, field) + case "__type": + out.Values[i] = ec._Query___type(ctx, field) + case "__schema": + out.Values[i] = ec._Query___schema(ctx, field) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) _Query_todos(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{ + Object: "Query", + Args: nil, + Field: field, + }) + return graphql.Defer(func() (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + userErr := ec.Recover(ctx, r) + ec.Error(ctx, userErr) + ret = graphql.Null + } + }() + + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return ec.resolvers.Query().Todos(ctx) + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]Todo) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec._Todo(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 + }) +} + +func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + args := map[string]interface{}{} + var arg0 string + if tmp, ok := field.Args["name"]; ok { + var err error + arg0, err = graphql.UnmarshalString(tmp) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + } + args["name"] = arg0 + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Query" + rctx.Args = args + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return ec.introspectType(args["name"].(string)), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Query" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return ec.introspectSchema(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Schema) + if res == nil { + return graphql.Null + } + return ec.___Schema(ctx, field.Selections, res) +} + +var todoImplementors = []string{"Todo"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _Todo(ctx context.Context, sel ast.SelectionSet, obj *Todo) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, todoImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Todo") + case "id": + out.Values[i] = ec._Todo_id(ctx, field, obj) + case "text": + out.Values[i] = ec._Todo_text(ctx, field, obj) + case "done": + out.Values[i] = ec._Todo_done(ctx, field, obj) + case "user": + out.Values[i] = ec._Todo_user(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) _Todo_id(ctx context.Context, field graphql.CollectedField, obj *Todo) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Todo" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.ID, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalID(res) +} + +func (ec *executionContext) _Todo_text(ctx context.Context, field graphql.CollectedField, obj *Todo) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Todo" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) _Todo_done(ctx context.Context, field graphql.CollectedField, obj *Todo) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Todo" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Done, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + return graphql.MarshalBoolean(res) +} + +func (ec *executionContext) _Todo_user(ctx context.Context, field graphql.CollectedField, obj *Todo) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "Todo" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.User, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(User) + return ec._User(ctx, field.Selections, &res) +} + +var userImplementors = []string{"User"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *User) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, userImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("User") + case "id": + out.Values[i] = ec._User_id(ctx, field, obj) + case "name": + out.Values[i] = ec._User_name(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) _User_id(ctx context.Context, field graphql.CollectedField, obj *User) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "User" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.ID, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalID(res) +} + +func (ec *executionContext) _User_name(ctx context.Context, field graphql.CollectedField, obj *User) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "User" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.FullName(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +var __DirectiveImplementors = []string{"__Directive"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___Directive(ctx context.Context, sel ast.SelectionSet, obj *introspection.Directive) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __DirectiveImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Directive") + case "name": + out.Values[i] = ec.___Directive_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Directive_description(ctx, field, obj) + case "locations": + out.Values[i] = ec.___Directive_locations(ctx, field, obj) + case "args": + out.Values[i] = ec.___Directive_args(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___Directive_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Directive" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Name, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Directive_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Directive" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Directive_locations(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Directive" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Locations, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]string) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return graphql.MarshalString(res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Directive_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Directive) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Directive" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Args, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___InputValue(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +var __EnumValueImplementors = []string{"__EnumValue"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___EnumValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.EnumValue) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __EnumValueImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__EnumValue") + case "name": + out.Values[i] = ec.___EnumValue_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___EnumValue_description(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___EnumValue_isDeprecated(ctx, field, obj) + case "deprecationReason": + out.Values[i] = ec.___EnumValue_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___EnumValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__EnumValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Name, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___EnumValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__EnumValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___EnumValue_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__EnumValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.IsDeprecated, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + return graphql.MarshalBoolean(res) +} + +func (ec *executionContext) ___EnumValue_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.EnumValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__EnumValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.DeprecationReason, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +var __FieldImplementors = []string{"__Field"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___Field(ctx context.Context, sel ast.SelectionSet, obj *introspection.Field) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __FieldImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Field") + case "name": + out.Values[i] = ec.___Field_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Field_description(ctx, field, obj) + case "args": + out.Values[i] = ec.___Field_args(ctx, field, obj) + case "type": + out.Values[i] = ec.___Field_type(ctx, field, obj) + case "isDeprecated": + out.Values[i] = ec.___Field_isDeprecated(ctx, field, obj) + case "deprecationReason": + out.Values[i] = ec.___Field_deprecationReason(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___Field_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Name, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Field_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Field_args(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Args, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___InputValue(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Field_type(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Type, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Field_isDeprecated(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.IsDeprecated, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(bool) + return graphql.MarshalBoolean(res) +} + +func (ec *executionContext) ___Field_deprecationReason(ctx context.Context, field graphql.CollectedField, obj *introspection.Field) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Field" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.DeprecationReason, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +var __InputValueImplementors = []string{"__InputValue"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___InputValue(ctx context.Context, sel ast.SelectionSet, obj *introspection.InputValue) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __InputValueImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__InputValue") + case "name": + out.Values[i] = ec.___InputValue_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___InputValue_description(ctx, field, obj) + case "type": + out.Values[i] = ec.___InputValue_type(ctx, field, obj) + case "defaultValue": + out.Values[i] = ec.___InputValue_defaultValue(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___InputValue_name(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__InputValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Name, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___InputValue_description(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__InputValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___InputValue_type(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__InputValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Type, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) ___InputValue_defaultValue(ctx context.Context, field graphql.CollectedField, obj *introspection.InputValue) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__InputValue" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.DefaultValue, nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +var __SchemaImplementors = []string{"__Schema"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___Schema(ctx context.Context, sel ast.SelectionSet, obj *introspection.Schema) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __SchemaImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Schema") + case "types": + out.Values[i] = ec.___Schema_types(ctx, field, obj) + case "queryType": + out.Values[i] = ec.___Schema_queryType(ctx, field, obj) + case "mutationType": + out.Values[i] = ec.___Schema_mutationType(ctx, field, obj) + case "subscriptionType": + out.Values[i] = ec.___Schema_subscriptionType(ctx, field, obj) + case "directives": + out.Values[i] = ec.___Schema_directives(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___Schema_types(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Schema" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Types(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___Type(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Schema_queryType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Schema" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.QueryType(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_mutationType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Schema" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.MutationType(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_subscriptionType(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Schema" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.SubscriptionType(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func (ec *executionContext) ___Schema_directives(ctx context.Context, field graphql.CollectedField, obj *introspection.Schema) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Schema" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Directives(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Directive) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___Directive(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +var __TypeImplementors = []string{"__Type"} + +// nolint: gocyclo, errcheck, gas, goconst +func (ec *executionContext) ___Type(ctx context.Context, sel ast.SelectionSet, obj *introspection.Type) graphql.Marshaler { + fields := graphql.CollectFields(ctx, sel, __TypeImplementors) + + out := graphql.NewOrderedMap(len(fields)) + for i, field := range fields { + out.Keys[i] = field.Alias + + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("__Type") + case "kind": + out.Values[i] = ec.___Type_kind(ctx, field, obj) + case "name": + out.Values[i] = ec.___Type_name(ctx, field, obj) + case "description": + out.Values[i] = ec.___Type_description(ctx, field, obj) + case "fields": + out.Values[i] = ec.___Type_fields(ctx, field, obj) + case "interfaces": + out.Values[i] = ec.___Type_interfaces(ctx, field, obj) + case "possibleTypes": + out.Values[i] = ec.___Type_possibleTypes(ctx, field, obj) + case "enumValues": + out.Values[i] = ec.___Type_enumValues(ctx, field, obj) + case "inputFields": + out.Values[i] = ec.___Type_inputFields(ctx, field, obj) + case "ofType": + out.Values[i] = ec.___Type_ofType(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + + return out +} + +func (ec *executionContext) ___Type_kind(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Kind(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Type_name(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Name(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Type_description(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Description(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(string) + return graphql.MarshalString(res) +} + +func (ec *executionContext) ___Type_fields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := field.Args["includeDeprecated"]; ok { + var err error + arg0, err = graphql.UnmarshalBoolean(tmp) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + } + args["includeDeprecated"] = arg0 + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = args + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Fields(args["includeDeprecated"].(bool)), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Field) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___Field(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Type_interfaces(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.Interfaces(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___Type(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Type_possibleTypes(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.PossibleTypes(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.Type) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___Type(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Type_enumValues(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + args := map[string]interface{}{} + var arg0 bool + if tmp, ok := field.Args["includeDeprecated"]; ok { + var err error + arg0, err = graphql.UnmarshalBoolean(tmp) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + } + args["includeDeprecated"] = arg0 + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = args + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.EnumValues(args["includeDeprecated"].(bool)), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.EnumValue) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___EnumValue(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Type_inputFields(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.InputFields(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]introspection.InputValue) + arr1 := graphql.Array{} + for idx1 := range res { + arr1 = append(arr1, func() graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.PushIndex(idx1) + defer rctx.Pop() + return ec.___InputValue(ctx, field.Selections, &res[idx1]) + }()) + } + return arr1 +} + +func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.CollectedField, obj *introspection.Type) graphql.Marshaler { + rctx := graphql.GetResolverContext(ctx) + rctx.Object = "__Type" + rctx.Args = nil + rctx.Field = field + rctx.PushField(field.Alias) + defer rctx.Pop() + resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) { + return obj.OfType(), nil + }) + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*introspection.Type) + if res == nil { + return graphql.Null + } + return ec.___Type(ctx, field.Selections, res) +} + +func UnmarshalNewTodo(v interface{}) (NewTodo, error) { + var it NewTodo + var asMap = v.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "text": + var err error + it.Text, err = graphql.UnmarshalString(v) + if err != nil { + return it, err + } + case "userId": + var err error + it.UserID, err = graphql.UnmarshalString(v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + +func (ec *executionContext) FieldMiddleware(ctx context.Context, next graphql.Resolver) interface{} { + res, err := ec.ResolverMiddleware(ctx, next) + if err != nil { + ec.Error(ctx, err) + return nil + } + return res +} + +func (ec *executionContext) introspectSchema() *introspection.Schema { + return introspection.WrapSchema(parsedSchema) +} + +func (ec *executionContext) introspectType(name string) *introspection.Type { + return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]) +} + +var parsedSchema = gqlparser.MustLoadSchema( + &ast.Source{Name: "schema.graphql", Input: `# GraphQL schema example +# +# https://gqlgen.com/getting-started/ + +type Todo { + id: ID! + text: String! + done: Boolean! + user: User! +} + +type User { + id: ID! + name: String! +} + +type Query { + todos: [Todo!]! +} + +input NewTodo { + text: String! + userId: String! +} + +type Mutation { + createTodo(input: NewTodo!): Todo! +} +`}, +) diff --git a/example/config/model.go b/example/config/model.go new file mode 100644 index 00000000000..46038be7f88 --- /dev/null +++ b/example/config/model.go @@ -0,0 +1,12 @@ +package config + +import "fmt" + +type User struct { + ID string + FirstName, LastName string +} + +func (user *User) FullName() string { + return fmt.Sprintf("%s %s", user.FirstName, user.LastName) +} diff --git a/example/config/models_gen.go b/example/config/models_gen.go new file mode 100644 index 00000000000..dc8e7849a7e --- /dev/null +++ b/example/config/models_gen.go @@ -0,0 +1,14 @@ +// Code generated by github.com/vektah/gqlgen, DO NOT EDIT. + +package config + +type NewTodo struct { + Text string `json:"text"` + UserID string `json:"userId"` +} +type Todo struct { + ID string `json:"id"` + Description string `json:"text"` + Done bool `json:"done"` + User User `json:"user"` +} diff --git a/example/config/resolver.go b/example/config/resolver.go new file mode 100644 index 00000000000..ef45581d676 --- /dev/null +++ b/example/config/resolver.go @@ -0,0 +1,56 @@ +//go:generate gorunpkg github.com/vektah/gqlgen + +package config + +import ( + "context" + "fmt" +) + +func New() Config { + c := Config{ + Resolvers: &Resolver{ + todos: []Todo{ + {ID: "TODO:1", Description: "A todo not to forget", Done: false}, + {ID: "TODO:2", Description: "This is the most important", Done: false}, + {ID: "TODO:3", Description: "Please do this or else", Done: false}, + }, + nextID: 3, + }, + } + return c +} + +type Resolver struct { + todos []Todo + nextID int +} + +func (r *Resolver) Mutation() MutationResolver { + return &mutationResolver{r} +} +func (r *Resolver) Query() QueryResolver { + return &queryResolver{r} +} + +type mutationResolver struct{ *Resolver } + +func (r *mutationResolver) CreateTodo(ctx context.Context, input NewTodo) (Todo, error) { + newID := r.nextID + r.nextID++ + + newTodo := Todo{ + ID: fmt.Sprintf("TODO:%d", newID), + Description: input.Text, + } + + r.todos = append(r.todos, newTodo) + + return newTodo, nil +} + +type queryResolver struct{ *Resolver } + +func (r *queryResolver) Todos(ctx context.Context) ([]Todo, error) { + return r.todos, nil +} diff --git a/example/config/schema.graphql b/example/config/schema.graphql new file mode 100644 index 00000000000..c6a91bb4808 --- /dev/null +++ b/example/config/schema.graphql @@ -0,0 +1,28 @@ +# GraphQL schema example +# +# https://gqlgen.com/getting-started/ + +type Todo { + id: ID! + text: String! + done: Boolean! + user: User! +} + +type User { + id: ID! + name: String! +} + +type Query { + todos: [Todo!]! +} + +input NewTodo { + text: String! + userId: String! +} + +type Mutation { + createTodo(input: NewTodo!): Todo! +} diff --git a/example/config/server/server.go b/example/config/server/server.go new file mode 100644 index 00000000000..b56e2b9b9b5 --- /dev/null +++ b/example/config/server/server.go @@ -0,0 +1,17 @@ +package main + +import ( + "log" + "net/http" + + todo "github.com/vektah/gqlgen/example/config" + "github.com/vektah/gqlgen/handler" +) + +func main() { + http.Handle("/", handler.Playground("Todo", "/query")) + http.Handle("/query", handler.GraphQL( + todo.NewExecutableSchema(todo.New()), + )) + log.Fatal(http.ListenAndServe(":8081", nil)) +}