Skip to content

Commit

Permalink
Merge pull request #221 from vektah/middleware-stack
Browse files Browse the repository at this point in the history
Implement FieldMiddleware Stack
  • Loading branch information
Mathew Byrne authored Jul 26, 2018
2 parents 66593ff + 0ec918b commit 803711e
Show file tree
Hide file tree
Showing 29 changed files with 733 additions and 1,787 deletions.
2 changes: 2 additions & 0 deletions codegen/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type Build struct {
SubscriptionRoot *Object
SchemaRaw string
SchemaFilename string
Directives []*Directive
}

type ModelBuild struct {
Expand Down Expand Up @@ -84,6 +85,7 @@ func (cfg *Config) bind() (*Build, error) {
Imports: imports.finalize(),
SchemaRaw: cfg.SchemaStr,
SchemaFilename: cfg.SchemaFilename,
Directives: cfg.buildDirectives(),
}

if cfg.schema.Query != nil {
Expand Down
5 changes: 5 additions & 0 deletions codegen/directive.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package codegen

type Directive struct {
Name string
}
13 changes: 13 additions & 0 deletions codegen/directive_build.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package codegen

func (cfg *Config) buildDirectives() (directives []*Directive) {
for name := range cfg.schema.Directives {
if name == "skip" || name == "include" || name == "deprecated" {
continue
}
directives = append(directives, &Directive{
Name: name,
})
}
return directives
}
4 changes: 2 additions & 2 deletions codegen/templates/data.go

Large diffs are not rendered by default.

6 changes: 1 addition & 5 deletions codegen/templates/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
rctx.PushField(field.Alias)
defer rctx.Pop()
{{- end }}
resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
resTmp := ec.FieldMiddleware(ctx, func(ctx context.Context) (interface{}, error) {
{{- if $field.IsResolver }}
return ec.resolvers.{{ $field.ShortInvocation }}
{{- else if $field.GoVarName }}
Expand All @@ -59,10 +59,6 @@
{{- end }}
{{- end }}
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
Expand Down
55 changes: 47 additions & 8 deletions codegen/templates/generated.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,16 @@ import (
)

// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema {
return &executableSchema{resolvers: resolvers}
func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
return &executableSchema{
resolvers: cfg.Resolvers,
directives: cfg.Directives,
}
}

type Config struct {
Resolvers ResolverRoot
Directives DirectiveRoot
}

type ResolverRoot interface {
Expand All @@ -21,6 +29,12 @@ type ResolverRoot interface {
{{- end }}
}

type DirectiveRoot struct {
{{ range $directive := .Directives }}
{{$directive.Name|ucFirst}} graphql.FieldMiddleware
{{ end }}
}

{{- range $object := .Objects -}}
{{ if $object.HasResolvers }}
type {{$object.GQLType}}Resolver interface {
Expand All @@ -32,7 +46,8 @@ type ResolverRoot interface {
{{- end }}

type executableSchema struct {
resolvers ResolverRoot
resolvers ResolverRoot
directives DirectiveRoot
}

func (e *executableSchema) Schema() *ast.Schema {
Expand All @@ -41,7 +56,7 @@ func (e *executableSchema) Schema() *ast.Schema {

func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
{{- if .QueryRoot }}
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}
ec := executionContext{graphql.GetRequestContext(ctx), e}

buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
data := ec._{{.QueryRoot.GQLType}}(ctx, op.SelectionSet)
Expand All @@ -61,7 +76,7 @@ func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinitio

func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
{{- if .MutationRoot }}
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}
ec := executionContext{graphql.GetRequestContext(ctx), e}

buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
data := ec._{{.MutationRoot.GQLType}}(ctx, op.SelectionSet)
Expand All @@ -81,7 +96,7 @@ func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefini

func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
{{- if .SubscriptionRoot }}
ec := executionContext{graphql.GetRequestContext(ctx), e.resolvers}
ec := executionContext{graphql.GetRequestContext(ctx), e}

next := ec._{{.SubscriptionRoot.GQLType}}(ctx, op.SelectionSet)
if ec.Errors != nil {
Expand Down Expand Up @@ -113,8 +128,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe

type executionContext struct {
*graphql.RequestContext

resolvers ResolverRoot
*executableSchema
}

{{- range $object := .Objects }}
Expand All @@ -133,6 +147,31 @@ type executionContext struct {
{{ template "input.gotpl" $input }}
{{- end }}

func (ec *executionContext) FieldMiddleware(ctx context.Context, next graphql.Resolver) interface{} {
{{- if .Directives }}
rctx := graphql.GetResolverContext(ctx)
for _, d := range rctx.Field.Definition.Directives {
switch d.Name {
{{- range $directive := .Directives }}
case "{{$directive.Name}}":
if ec.directives.{{$directive.Name|ucFirst}} != nil {
n := next
next = func(ctx context.Context) (interface{}, error) {
return ec.directives.{{$directive.Name|ucFirst}}(ctx, n)
}
}
{{- end }}
}
}
{{- end }}
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)
}
Expand Down
Loading

0 comments on commit 803711e

Please sign in to comment.