Skip to content

Commit

Permalink
Merge pull request #65 from vektah/context
Browse files Browse the repository at this point in the history
Make field selections available in context
  • Loading branch information
vektah authored Mar 28, 2018
2 parents 4e13262 + c60336b commit 71c4e26
Show file tree
Hide file tree
Showing 25 changed files with 2,195 additions and 1,271 deletions.
4 changes: 2 additions & 2 deletions codegen/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (f *Field) CallArgs() string {
var args []string

if f.GoMethodName == "" {
args = append(args, "ec.ctx")
args = append(args, "rctx")

if !f.Object.Root {
args = append(args, "obj")
Expand Down Expand Up @@ -134,7 +134,7 @@ func (f *Field) doWriteJson(val string, remainingMods []string, isPtr bool, dept
if !isPtr {
val = "&" + val
}
return fmt.Sprintf("return ec._%s(field.Selections, %s)", f.GQLType, val)
return fmt.Sprintf("return ec._%s(ctx, field.Selections, %s)", f.GQLType, val)
}
}

Expand Down
8 changes: 4 additions & 4 deletions codegen/templates/data.go

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions codegen/templates/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@
{{ $object := $field.Object }}

{{- if $object.Stream }}
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(field graphql.CollectedField) func() graphql.Marshaler {
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField) func() graphql.Marshaler {
{{- template "args.gotpl" $field.Args }}
rctx := graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})
results, err := ec.resolvers.{{ $object.GQLType }}_{{ $field.GQLName }}({{ $field.CallArgs }})
if err != nil {
ec.Error(err)
Expand All @@ -20,14 +21,14 @@
}
}
{{ else }}
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {
func (ec *executionContext) _{{$object.GQLType}}_{{$field.GQLName}}(ctx context.Context, field graphql.CollectedField, {{if not $object.Root}}obj *{{$object.FullName}}{{end}}) graphql.Marshaler {
{{- template "args.gotpl" $field.Args }}

{{- if $field.IsConcurrent }}
return graphql.Defer(func() (ret graphql.Marshaler) {
defer func() {
if r := recover(); r != nil {
userErr := ec.recover(r)
userErr := ec.Recover(r)
ec.Error(userErr)
ret = graphql.Null
}
Expand All @@ -47,6 +48,7 @@
}
{{- end }}
{{- else }}
rctx := graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field})
res, err := ec.resolvers.{{ $object.GQLType }}_{{ $field.GQLName }}({{ $field.CallArgs }})
if err != nil {
ec.Error(err)
Expand Down
49 changes: 13 additions & 36 deletions codegen/templates/generated.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ import (
{{ end }}
)

func MakeExecutableSchema(resolvers Resolvers, opts ...ExecutableOption) graphql.ExecutableSchema {
ret := &executableSchema{resolvers: resolvers}
for _, opt := range opts {
opt(ret)
}
return ret
func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema {
return &executableSchema{resolvers: resolvers}
}

type Resolvers interface {
Expand All @@ -24,28 +20,19 @@ type Resolvers interface {
{{- end }}
}

type ExecutableOption func(*executableSchema)

func WithErrorConverter(fn func(error) string) ExecutableOption {
return func(s *executableSchema) {
s.errorMessageFn = fn
}
}

type executableSchema struct {
resolvers Resolvers
errorMessageFn func(error) string
}

func (e *executableSchema) Schema() *schema.Schema {
return parsedSchema
}

func (e *executableSchema) Query(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
func (e *executableSchema) Query(ctx context.Context, op *query.Operation) *graphql.Response {
{{- if .QueryRoot }}
ec := e.makeExecutionContext(ctx, doc, variables, recover)
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}

data := ec._{{.QueryRoot.GQLType}}(op.Selections)
data := ec._{{.QueryRoot.GQLType}}(ctx, op.Selections)
var buf bytes.Buffer
data.MarshalGQL(&buf)

Expand All @@ -58,11 +45,11 @@ func (e *executableSchema) Query(ctx context.Context, doc *query.Document, varia
{{- end }}
}

func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) *graphql.Response {
func (e *executableSchema) Mutation(ctx context.Context, op *query.Operation) *graphql.Response {
{{- if .MutationRoot }}
ec := e.makeExecutionContext(ctx, doc, variables, recover)
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}

data := ec._{{.MutationRoot.GQLType}}(op.Selections)
data := ec._{{.MutationRoot.GQLType}}(ctx, op.Selections)
var buf bytes.Buffer
data.MarshalGQL(&buf)

Expand All @@ -75,11 +62,11 @@ func (e *executableSchema) Mutation(ctx context.Context, doc *query.Document, va
{{- end }}
}

func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document, variables map[string]interface{}, op *query.Operation, recover graphql.RecoverFunc) func() *graphql.Response {
func (e *executableSchema) Subscription(ctx context.Context, op *query.Operation) func() *graphql.Response {
{{- if .SubscriptionRoot }}
ec := e.makeExecutionContext(ctx, doc, variables, recover)
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}

next := ec._{{.SubscriptionRoot.GQLType}}(op.Selections)
next := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.Selections)
if ec.Errors != nil {
return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors})
}
Expand All @@ -105,20 +92,10 @@ func (e *executableSchema) Subscription(ctx context.Context, doc *query.Document
{{- end }}
}

func (e *executableSchema) makeExecutionContext(ctx context.Context, doc *query.Document, variables map[string]interface{}, recover graphql.RecoverFunc) *executionContext {
errBuilder := errors.Builder{ErrorMessageFn: e.errorMessageFn}
return &executionContext{
Builder: errBuilder, resolvers: e.resolvers, variables: variables, doc: doc, ctx: ctx, recover: recover,
}
}

type executionContext struct {
errors.Builder
*graphql.RequestContext

resolvers Resolvers
variables map[string]interface{}
doc *query.Document
ctx context.Context
recover graphql.RecoverFunc
}

{{- range $object := .Objects }}
Expand Down
6 changes: 3 additions & 3 deletions codegen/templates/interface.gotpl
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
{{- $interface := . }}

func (ec *executionContext) _{{$interface.GQLType}}(sel []query.Selection, obj *{{$interface.FullName}}) graphql.Marshaler {
func (ec *executionContext) _{{$interface.GQLType}}(ctx context.Context, sel []query.Selection, obj *{{$interface.FullName}}) graphql.Marshaler {
switch obj := (*obj).(type) {
case nil:
return graphql.Null
{{- range $implementor := $interface.Implementors }}
{{- if $implementor.ValueReceiver }}
case {{$implementor.FullName}}:
return ec._{{$implementor.GQLType}}(sel, &obj)
return ec._{{$implementor.GQLType}}(ctx, sel, &obj)
{{- end}}
case *{{$implementor.FullName}}:
return ec._{{$implementor.GQLType}}(sel, obj)
return ec._{{$implementor.GQLType}}(ctx, sel, obj)
{{- end }}
default:
panic(fmt.Errorf("unexpected type %T", obj))
Expand Down
12 changes: 6 additions & 6 deletions codegen/templates/object.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ var {{ $object.GQLType|lcFirst}}Implementors = {{$object.Implementors}}

// nolint: gocyclo, errcheck, gas, goconst
{{- if .Stream }}
func (ec *executionContext) _{{$object.GQLType}}(sel []query.Selection) func() graphql.Marshaler {
fields := graphql.CollectFields(ec.doc, sel, {{$object.GQLType|lcFirst}}Implementors, ec.variables)
func (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel []query.Selection) func() graphql.Marshaler {
fields := graphql.CollectFields(ec.Doc, sel, {{$object.GQLType|lcFirst}}Implementors, ec.Variables)

if len(fields) != 1 {
ec.Errorf("must subscribe to exactly one stream")
Expand All @@ -15,15 +15,15 @@ func (ec *executionContext) _{{$object.GQLType}}(sel []query.Selection) func() g
switch fields[0].Name {
{{- range $field := $object.Fields }}
case "{{$field.GQLName}}":
return ec._{{$object.GQLType}}_{{$field.GQLName}}(fields[0])
return ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, fields[0])
{{- end }}
default:
panic("unknown field " + strconv.Quote(fields[0].Name))
}
}
{{- else }}
func (ec *executionContext) _{{$object.GQLType}}(sel []query.Selection{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {
fields := graphql.CollectFields(ec.doc, sel, {{$object.GQLType|lcFirst}}Implementors, ec.variables)
func (ec *executionContext) _{{$object.GQLType}}(ctx context.Context, sel []query.Selection{{if not $object.Root}}, obj *{{$object.FullName}} {{end}}) graphql.Marshaler {
fields := graphql.CollectFields(ec.Doc, sel, {{$object.GQLType|lcFirst}}Implementors, ec.Variables)
out := graphql.NewOrderedMap(len(fields))
for i, field := range fields {
out.Keys[i] = field.Alias
Expand All @@ -33,7 +33,7 @@ func (ec *executionContext) _{{$object.GQLType}}(sel []query.Selection{{if not $
out.Values[i] = graphql.MarshalString({{$object.GQLType|quote}})
{{- range $field := $object.Fields }}
case "{{$field.GQLName}}":
out.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(field{{if not $object.Root}}, obj{{end}})
out.Values[i] = ec._{{$object.GQLType}}_{{$field.GQLName}}(ctx, field{{if not $object.Root}}, obj{{end}})
{{- end }}
default:
panic("unknown field " + strconv.Quote(field.Name))
Expand Down
Loading

0 comments on commit 71c4e26

Please sign in to comment.