Skip to content

Commit

Permalink
Merge pull request 99designs#885 from 99designs/handler-refactor
Browse files Browse the repository at this point in the history
Refactor handler package
  • Loading branch information
vektah authored Nov 28, 2019
2 parents 3296f6b + ab761b2 commit baf2f40
Show file tree
Hide file tree
Showing 127 changed files with 8,394 additions and 9,145 deletions.
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ linters:
- staticcheck
- structcheck
- stylecheck
- typecheck
- unconvert
- unused
- varcheck
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ build: false
deploy: false

test_script:
- git clean -ffdx
- go generate ./...
- go test -timeout 20m ./...
1 change: 1 addition & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/urfave/cli"

// Required since otherwise dep will prune away these unused packages before codegen has a chance to run
_ "github.com/99designs/gqlgen/graphql/handler"
_ "github.com/99designs/gqlgen/handler"
)

Expand Down
4 changes: 2 additions & 2 deletions codegen/directives.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ func (ec *executionContext) _subscriptionMiddleware(ctx context.Context, obj *as
{{ if .Directives.LocationDirectives "FIELD" }}
func (ec *executionContext) _fieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) interface{} {
{{- if .Directives.LocationDirectives "FIELD" }}
rctx := graphql.GetResolverContext(ctx)
for _, d := range rctx.Field.Directives {
fc := graphql.GetFieldContext(ctx)
for _, d := range fc.Field.Directives {
switch d.Name {
{{- range $directive := .Directives.LocationDirectives "FIELD" }}
case "{{$directive.Name}}":
Expand Down
15 changes: 6 additions & 9 deletions codegen/field.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,29 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
{{- if $object.Stream }}
{{- $null = "nil" }}
{{- end }}
ctx = ec.Tracer.StartFieldExecution(ctx, field)
defer func () {
if r := recover(); r != nil {
ec.Error(ctx, ec.Recover(ctx, r))
ret = {{ $null }}
}
ec.Tracer.EndFieldExecution(ctx)
}()
rctx := &graphql.ResolverContext{
fc := &graphql.FieldContext{
Object: {{$object.Name|quote}},
Field: field,
Args: nil,
IsMethod: {{or $field.IsMethod $field.IsResolver}},
}
ctx = graphql.WithResolverContext(ctx, rctx)

ctx = graphql.WithFieldContext(ctx, fc)
{{- if $field.Args }}
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.{{ $field.ArgsFunc }}(ctx,rawArgs)
if err != nil {
ec.Error(ctx, err)
return {{ $null }}
}
rctx.Args = args
fc.Args = args
{{- end }}
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
{{- if $.Directives.LocationDirectives "FIELD" }}
resTmp := ec._fieldMiddleware(ctx, {{if $object.Root}}nil{{else}}obj{{end}}, func(rctx context.Context) (interface{}, error) {
{{ template "field" $field }}
Expand All @@ -45,7 +43,7 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
{{- end }}
if resTmp == nil {
{{- if $field.TypeReference.GQL.NonNull }}
if !ec.HasError(rctx) {
if !graphql.HasFieldError(ctx, fc) {
ec.Errorf(ctx, "must not be null")
}
{{- end }}
Expand All @@ -67,8 +65,7 @@ func (ec *executionContext) _{{$object.Name}}_{{$field.Name}}(ctx context.Contex
}
{{- else }}
res := resTmp.({{$field.TypeReference.GO | ref}})
rctx.Result = res
ctx = ec.Tracer.StartFieldChildExecution(ctx)
fc.Result = res
return ec.{{ $field.TypeReference.MarshalFunc }}(ctx, field.Selections, res)
{{- end }}
}
Expand Down
124 changes: 51 additions & 73 deletions codegen/generated!.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -112,105 +112,83 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return 0, false
}

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

buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
{{ if .Directives.LocationDirectives "QUERY" -}}
data := ec._queryMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
return ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet), nil
})
{{- else -}}
data := ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet)
{{- end }}
func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler {
rc := graphql.GetOperationContext(ctx)
ec := executionContext{rc, e}
first := true

switch rc.Operation.Operation {
{{- if .QueryRoot }} case ast.Query:
return func(ctx context.Context) *graphql.Response {
if !first { return nil }
first = false
{{ if .Directives.LocationDirectives "QUERY" -}}
data := ec._queryMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
return ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
})
{{- else -}}
data := ec._{{.QueryRoot.Name}}(ctx, rc.Operation.SelectionSet)
{{- end }}
var buf bytes.Buffer
data.MarshalGQL(&buf)
return buf.Bytes()
})

return &graphql.Response{
Data: buf,
Errors: ec.Errors,
Extensions: ec.Extensions,
return &graphql.Response{
Data: buf.Bytes(),
}
}
{{- else }}
return graphql.ErrorResponse(ctx, "queries are not supported")
{{- end }}
}

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

buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
{{ if .Directives.LocationDirectives "MUTATION" -}}
data := ec._mutationMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
return ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet), nil
})
{{- else -}}
data := ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet)
{{- end }}
{{- if .MutationRoot }} case ast.Mutation:
return func(ctx context.Context) *graphql.Response {
if !first { return nil }
first = false
{{ if .Directives.LocationDirectives "MUTATION" -}}
data := ec._mutationMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
return ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet), nil
})
{{- else -}}
data := ec._{{.MutationRoot.Name}}(ctx, rc.Operation.SelectionSet)
{{- end }}
var buf bytes.Buffer
data.MarshalGQL(&buf)
return buf.Bytes()
})

return &graphql.Response{
Data: buf,
Errors: ec.Errors,
Extensions: ec.Extensions,
return &graphql.Response{
Data: buf.Bytes(),
}
}
{{- else }}
return graphql.ErrorResponse(ctx, "mutations are not supported")
{{- end }}
}

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

{{- if .SubscriptionRoot }} case ast.Subscription:
{{ if .Directives.LocationDirectives "SUBSCRIPTION" -}}
next := ec._subscriptionMiddleware(ctx, op, func(ctx context.Context) (interface{}, error){
return ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet),nil
next := ec._subscriptionMiddleware(ctx, rc.Operation, func(ctx context.Context) (interface{}, error){
return ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet),nil
})
{{- else -}}
next := ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet)
next := ec._{{.SubscriptionRoot.Name}}(ctx, rc.Operation.SelectionSet)
{{- end }}
if ec.Errors != nil {
return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors})
}

var buf bytes.Buffer
return func() *graphql.Response {
buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
buf.Reset()
data := next()

if data == nil {
return nil
}
data.MarshalGQL(&buf)
return buf.Bytes()
})
return func(ctx context.Context) *graphql.Response {
buf.Reset()
data := next()

if buf == nil {
if data == nil {
return nil
}
data.MarshalGQL(&buf)

return &graphql.Response{
Data: buf,
Errors: ec.Errors,
Extensions: ec.Extensions,
Data: buf.Bytes(),
}
}
{{- else }}
return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported"))
{{- end }}
{{ end }}
default:
return graphql.OneShot(graphql.ErrorResponse(ctx, "unsupported GraphQL operation"))
}
}

type executionContext struct {
*graphql.RequestContext
*graphql.OperationContext
*executableSchema
}

Expand Down
8 changes: 4 additions & 4 deletions codegen/object.gotpl
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ var {{ $object.Name|lcFirst}}Implementors = {{$object.Implementors}}

{{- if .Stream }}
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet) func() graphql.Marshaler {
fields := graphql.CollectFields(ec.RequestContext, sel, {{$object.Name|lcFirst}}Implementors)
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
Object: {{$object.Name|quote}},
})
if len(fields) != 1 {
Expand All @@ -24,9 +24,9 @@ func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.Selec
}
{{- else }}
func (ec *executionContext) _{{$object.Name}}(ctx context.Context, sel ast.SelectionSet{{ if not $object.Root }},obj {{$object.Reference | ref }}{{ end }}) graphql.Marshaler {
fields := graphql.CollectFields(ec.RequestContext, sel, {{$object.Name|lcFirst}}Implementors)
fields := graphql.CollectFields(ec.OperationContext, sel, {{$object.Name|lcFirst}}Implementors)
{{if $object.Root}}
ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{
ctx = graphql.WithFieldContext(ctx, &graphql.FieldContext{
Object: {{$object.Name|quote}},
})
{{end}}
Expand Down
11 changes: 8 additions & 3 deletions codegen/testserver/complexity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,17 @@ import (
"testing"

"github.com/99designs/gqlgen/client"
"github.com/99designs/gqlgen/handler"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/handler/extension"
"github.com/stretchr/testify/require"
)

func TestComplexityCollisions(t *testing.T) {
resolvers := &Stub{}

c := client.New(handler.GraphQL(NewExecutableSchema(Config{Resolvers: resolvers})))
srv := handler.NewDefaultServer(NewExecutableSchema(Config{Resolvers: resolvers}))

c := client.New(srv)

resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) {
return &OverlappingFields{
Expand Down Expand Up @@ -48,7 +51,9 @@ func TestComplexityFuncs(t *testing.T) {
cfg.Complexity.OverlappingFields.Foo = func(childComplexity int) int { return 1000 }
cfg.Complexity.OverlappingFields.NewFoo = func(childComplexity int) int { return 5 }

c := client.New(handler.GraphQL(NewExecutableSchema(cfg), handler.ComplexityLimit(10)))
srv := handler.NewDefaultServer(NewExecutableSchema(cfg))
srv.Use(extension.FixedComplexityLimit(10))
c := client.New(srv)

resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) {
return &OverlappingFields{
Expand Down
Loading

0 comments on commit baf2f40

Please sign in to comment.