diff --git a/codegen/complexity.go b/codegen/complexity.go index 66d21a840e5..e9c6a20ee83 100644 --- a/codegen/complexity.go +++ b/codegen/complexity.go @@ -1,10 +1,10 @@ package codegen -func (o *Object) UniqueFields() map[string]*Field { - m := map[string]*Field{} +func (o *Object) UniqueFields() map[string][]*Field { + m := map[string][]*Field{} for _, f := range o.Fields { - m[f.GoFieldName] = f + m[f.GoFieldName] = append(m[f.GoFieldName], f) } return m diff --git a/codegen/generated!.gotpl b/codegen/generated!.gotpl index dce8ce977c7..dc8095de20e 100644 --- a/codegen/generated!.gotpl +++ b/codegen/generated!.gotpl @@ -46,7 +46,8 @@ type ComplexityRoot struct { {{ range $object := .Objects }} {{ if not $object.IsReserved -}} {{ $object.Name|go }} struct { - {{ range $field := $object.UniqueFields -}} + {{ range $_, $fields := $object.UniqueFields }} + {{- $field := index $fields 0 -}} {{ if not $field.IsReserved -}} {{ $field.GoFieldName }} {{ $field.ComplexitySignature }} {{ end }} @@ -84,20 +85,25 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in switch typeName + "." + field { {{ range $object := .Objects }} {{ if not $object.IsReserved }} - {{ range $field := $object.UniqueFields }} - {{ if not $field.IsReserved }} - case "{{$object.Name}}.{{$field.GoFieldName}}": - if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil { - break - } - {{ if $field.Args }} - args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) - if err != nil { - return 0, false + {{ range $_, $fields := $object.UniqueFields }} + {{- $len := len $fields }} + {{- range $i, $field := $fields }} + {{- $last := eq (add $i 1) $len }} + {{- if not $field.IsReserved }} + {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}: + if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil { + break } + {{ if $field.Args }} + args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs) + if err != nil { + return 0, false + } + {{ end }} + return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true {{ end }} - return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{end}}), true - {{ end }} + {{- end }} + {{- end }} {{ end }} {{ end }} {{ end }} diff --git a/codegen/testserver/complexity_test.go b/codegen/testserver/complexity_test.go index 2457eda8e88..9caca33f0ca 100644 --- a/codegen/testserver/complexity_test.go +++ b/codegen/testserver/complexity_test.go @@ -42,5 +42,76 @@ func TestComplexityCollisions(t *testing.T) { require.Equal(t, 2, resp.Overlapping.OldFoo) require.Equal(t, 3, resp.Overlapping.NewFoo) require.Equal(t, 3, resp.Overlapping.New_foo) +} + +func TestComplexityFuncs(t *testing.T) { + resolvers := &Stub{} + cfg := Config{Resolvers: resolvers} + cfg.Complexity.OverlappingFields.Foo = func(childComplexity int) int { return 1000 } + cfg.Complexity.OverlappingFields.NewFoo = func(childComplexity int) int { return 5 } + + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(cfg), handler.ComplexityLimit(10))) + c := client.New(srv.URL) + + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + t.Run("with high complexity limit will not run", func(t *testing.T) { + ran := false + resolvers.OverlappingFieldsResolver.OldFoo = func(ctx context.Context, obj *OverlappingFields) (i int, e error) { + ran = true + return obj.Foo, nil + } + + var resp struct { + Overlapping interface{} + } + err := c.Post(`query { overlapping { oneFoo, twoFoo, oldFoo, newFoo, new_foo } }`, &resp) + + require.EqualError(t, err, `http 422: {"errors":[{"message":"operation has complexity 2012, which exceeds the limit of 10"}],"data":null}`) + require.False(t, ran) + }) + + t.Run("with low complexity will run", func(t *testing.T) { + ran := false + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + ran = true + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + var resp struct { + Overlapping interface{} + } + c.MustPost(`query { overlapping { newFoo } }`, &resp) + + require.True(t, ran) + }) + + t.Run("with multiple low complexity will not run", func(t *testing.T) { + ran := false + resolvers.QueryResolver.Overlapping = func(ctx context.Context) (fields *OverlappingFields, e error) { + ran = true + return &OverlappingFields{ + Foo: 2, + NewFoo: 3, + }, nil + } + + var resp interface{} + err := c.Post(`query { + a: overlapping { newFoo }, + b: overlapping { newFoo }, + c: overlapping { newFoo }, + }`, &resp) + require.EqualError(t, err, `http 422: {"errors":[{"message":"operation has complexity 18, which exceeds the limit of 10"}],"data":null}`) + require.False(t, ran) + }) } diff --git a/codegen/testserver/generated.go b/codegen/testserver/generated.go index ea9638c0e6f..6500a011314 100644 --- a/codegen/testserver/generated.go +++ b/codegen/testserver/generated.go @@ -299,84 +299,84 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "A.ID": + case "A.id": if e.complexity.A.ID == nil { break } return e.complexity.A.ID(childComplexity), true - case "AIt.ID": + case "AIt.id": if e.complexity.AIt.ID == nil { break } return e.complexity.AIt.ID(childComplexity), true - case "AbIt.ID": + case "AbIt.id": if e.complexity.AbIt.ID == nil { break } return e.complexity.AbIt.ID(childComplexity), true - case "Autobind.IdInt": + case "Autobind.idInt": if e.complexity.Autobind.IdInt == nil { break } return e.complexity.Autobind.IdInt(childComplexity), true - case "Autobind.IdStr": + case "Autobind.idStr": if e.complexity.Autobind.IdStr == nil { break } return e.complexity.Autobind.IdStr(childComplexity), true - case "Autobind.Int": + case "Autobind.int": if e.complexity.Autobind.Int == nil { break } return e.complexity.Autobind.Int(childComplexity), true - case "Autobind.Int32": + case "Autobind.int32": if e.complexity.Autobind.Int32 == nil { break } return e.complexity.Autobind.Int32(childComplexity), true - case "Autobind.Int64": + case "Autobind.int64": if e.complexity.Autobind.Int64 == nil { break } return e.complexity.Autobind.Int64(childComplexity), true - case "B.ID": + case "B.id": if e.complexity.B.ID == nil { break } return e.complexity.B.ID(childComplexity), true - case "Circle.Area": + case "Circle.area": if e.complexity.Circle.Area == nil { break } return e.complexity.Circle.Area(childComplexity), true - case "Circle.Radius": + case "Circle.radius": if e.complexity.Circle.Radius == nil { break } return e.complexity.Circle.Radius(childComplexity), true - case "EmbeddedDefaultScalar.Value": + case "EmbeddedDefaultScalar.value": if e.complexity.EmbeddedDefaultScalar.Value == nil { break } @@ -397,133 +397,133 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.EmbeddedPointer.Title(childComplexity), true - case "Error.ErrorOnNonRequiredField": + case "Error.errorOnNonRequiredField": if e.complexity.Error.ErrorOnNonRequiredField == nil { break } return e.complexity.Error.ErrorOnNonRequiredField(childComplexity), true - case "Error.ErrorOnRequiredField": + case "Error.errorOnRequiredField": if e.complexity.Error.ErrorOnRequiredField == nil { break } return e.complexity.Error.ErrorOnRequiredField(childComplexity), true - case "Error.ID": + case "Error.id": if e.complexity.Error.ID == nil { break } return e.complexity.Error.ID(childComplexity), true - case "Error.NilOnRequiredField": + case "Error.nilOnRequiredField": if e.complexity.Error.NilOnRequiredField == nil { break } return e.complexity.Error.NilOnRequiredField(childComplexity), true - case "ForcedResolver.Field": + case "ForcedResolver.field": if e.complexity.ForcedResolver.Field == nil { break } return e.complexity.ForcedResolver.Field(childComplexity), true - case "InnerObject.ID": + case "InnerObject.id": if e.complexity.InnerObject.ID == nil { break } return e.complexity.InnerObject.ID(childComplexity), true - case "InvalidIdentifier.ID": + case "InvalidIdentifier.id": if e.complexity.InvalidIdentifier.ID == nil { break } return e.complexity.InvalidIdentifier.ID(childComplexity), true - case "It.ID": + case "It.id": if e.complexity.It.ID == nil { break } return e.complexity.It.ID(childComplexity), true - case "Map.ID": + case "Map.id": if e.complexity.Map.ID == nil { break } return e.complexity.Map.ID(childComplexity), true - case "MapStringInterfaceType.A": + case "MapStringInterfaceType.a": if e.complexity.MapStringInterfaceType.A == nil { break } return e.complexity.MapStringInterfaceType.A(childComplexity), true - case "MapStringInterfaceType.B": + case "MapStringInterfaceType.b": if e.complexity.MapStringInterfaceType.B == nil { break } return e.complexity.MapStringInterfaceType.B(childComplexity), true - case "ModelMethods.NoContext": + case "ModelMethods.noContext": if e.complexity.ModelMethods.NoContext == nil { break } return e.complexity.ModelMethods.NoContext(childComplexity), true - case "ModelMethods.ResolverField": + case "ModelMethods.resolverField": if e.complexity.ModelMethods.ResolverField == nil { break } return e.complexity.ModelMethods.ResolverField(childComplexity), true - case "ModelMethods.WithContext": + case "ModelMethods.withContext": if e.complexity.ModelMethods.WithContext == nil { break } return e.complexity.ModelMethods.WithContext(childComplexity), true - case "OuterObject.Inner": + case "OuterObject.inner": if e.complexity.OuterObject.Inner == nil { break } return e.complexity.OuterObject.Inner(childComplexity), true - case "OverlappingFields.Foo": + case "OverlappingFields.oneFoo", "OverlappingFields.twoFoo": if e.complexity.OverlappingFields.Foo == nil { break } return e.complexity.OverlappingFields.Foo(childComplexity), true - case "OverlappingFields.NewFoo": + case "OverlappingFields.newFoo", "OverlappingFields.new_foo": if e.complexity.OverlappingFields.NewFoo == nil { break } return e.complexity.OverlappingFields.NewFoo(childComplexity), true - case "OverlappingFields.OldFoo": + case "OverlappingFields.oldFoo": if e.complexity.OverlappingFields.OldFoo == nil { break } return e.complexity.OverlappingFields.OldFoo(childComplexity), true - case "Panics.ArgUnmarshal": + case "Panics.argUnmarshal": if e.complexity.Panics.ArgUnmarshal == nil { break } @@ -535,7 +535,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Panics.ArgUnmarshal(childComplexity, args["u"].([]MarshalPanic)), true - case "Panics.FieldFuncMarshal": + case "Panics.fieldFuncMarshal": if e.complexity.Panics.FieldFuncMarshal == nil { break } @@ -547,28 +547,28 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Panics.FieldFuncMarshal(childComplexity, args["u"].([]MarshalPanic)), true - case "Panics.FieldScalarMarshal": + case "Panics.fieldScalarMarshal": if e.complexity.Panics.FieldScalarMarshal == nil { break } return e.complexity.Panics.FieldScalarMarshal(childComplexity), true - case "Query.Autobind": + case "Query.autobind": if e.complexity.Query.Autobind == nil { break } return e.complexity.Query.Autobind(childComplexity), true - case "Query.Collision": + case "Query.collision": if e.complexity.Query.Collision == nil { break } return e.complexity.Query.Collision(childComplexity), true - case "Query.DefaultScalar": + case "Query.defaultScalar": if e.complexity.Query.DefaultScalar == nil { break } @@ -580,14 +580,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DefaultScalar(childComplexity, args["arg"].(string)), true - case "Query.DeprecatedField": + case "Query.deprecatedField": if e.complexity.Query.DeprecatedField == nil { break } return e.complexity.Query.DeprecatedField(childComplexity), true - case "Query.DirectiveArg": + case "Query.directiveArg": if e.complexity.Query.DirectiveArg == nil { break } @@ -599,7 +599,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DirectiveArg(childComplexity, args["arg"].(string)), true - case "Query.DirectiveInput": + case "Query.directiveInput": if e.complexity.Query.DirectiveInput == nil { break } @@ -611,7 +611,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DirectiveInput(childComplexity, args["arg"].(InputDirectives)), true - case "Query.DirectiveInputNullable": + case "Query.directiveInputNullable": if e.complexity.Query.DirectiveInputNullable == nil { break } @@ -623,7 +623,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DirectiveInputNullable(childComplexity, args["arg"].(*InputDirectives)), true - case "Query.DirectiveInputType": + case "Query.directiveInputType": if e.complexity.Query.DirectiveInputType == nil { break } @@ -635,7 +635,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DirectiveInputType(childComplexity, args["arg"].(InnerInput)), true - case "Query.DirectiveNullableArg": + case "Query.directiveNullableArg": if e.complexity.Query.DirectiveNullableArg == nil { break } @@ -647,14 +647,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.DirectiveNullableArg(childComplexity, args["arg"].(*int), args["arg2"].(*int)), true - case "Query.ErrorBubble": + case "Query.errorBubble": if e.complexity.Query.ErrorBubble == nil { break } return e.complexity.Query.ErrorBubble(childComplexity), true - case "Query.Fallback": + case "Query.fallback": if e.complexity.Query.Fallback == nil { break } @@ -666,7 +666,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Fallback(childComplexity, args["arg"].(FallbackToStringEncoding)), true - case "Query.InputSlice": + case "Query.inputSlice": if e.complexity.Query.InputSlice == nil { break } @@ -678,14 +678,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.InputSlice(childComplexity, args["arg"].([]string)), true - case "Query.InvalidIdentifier": + case "Query.invalidIdentifier": if e.complexity.Query.InvalidIdentifier == nil { break } return e.complexity.Query.InvalidIdentifier(childComplexity), true - case "Query.MapInput": + case "Query.mapInput": if e.complexity.Query.MapInput == nil { break } @@ -697,7 +697,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.MapInput(childComplexity, args["input"].(map[string]interface{})), true - case "Query.MapStringInterface": + case "Query.mapStringInterface": if e.complexity.Query.MapStringInterface == nil { break } @@ -709,14 +709,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.MapStringInterface(childComplexity, args["in"].(map[string]interface{})), true - case "Query.ModelMethods": + case "Query.modelMethods": if e.complexity.Query.ModelMethods == nil { break } return e.complexity.Query.ModelMethods(childComplexity), true - case "Query.NestedInputs": + case "Query.nestedInputs": if e.complexity.Query.NestedInputs == nil { break } @@ -728,14 +728,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.NestedInputs(childComplexity, args["input"].([][]*OuterInput)), true - case "Query.NestedOutputs": + case "Query.nestedOutputs": if e.complexity.Query.NestedOutputs == nil { break } return e.complexity.Query.NestedOutputs(childComplexity), true - case "Query.NullableArg": + case "Query.nullableArg": if e.complexity.Query.NullableArg == nil { break } @@ -747,28 +747,28 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.NullableArg(childComplexity, args["arg"].(*int)), true - case "Query.OptionalUnion": + case "Query.optionalUnion": if e.complexity.Query.OptionalUnion == nil { break } return e.complexity.Query.OptionalUnion(childComplexity), true - case "Query.Overlapping": + case "Query.overlapping": if e.complexity.Query.Overlapping == nil { break } return e.complexity.Query.Overlapping(childComplexity), true - case "Query.Panics": + case "Query.panics": if e.complexity.Query.Panics == nil { break } return e.complexity.Query.Panics(childComplexity), true - case "Query.Recursive": + case "Query.recursive": if e.complexity.Query.Recursive == nil { break } @@ -780,35 +780,35 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Recursive(childComplexity, args["input"].(*RecursiveInputSlice)), true - case "Query.ScalarSlice": + case "Query.scalarSlice": if e.complexity.Query.ScalarSlice == nil { break } return e.complexity.Query.ScalarSlice(childComplexity), true - case "Query.ShapeUnion": + case "Query.shapeUnion": if e.complexity.Query.ShapeUnion == nil { break } return e.complexity.Query.ShapeUnion(childComplexity), true - case "Query.Shapes": + case "Query.shapes": if e.complexity.Query.Shapes == nil { break } return e.complexity.Query.Shapes(childComplexity), true - case "Query.Slices": + case "Query.slices": if e.complexity.Query.Slices == nil { break } return e.complexity.Query.Slices(childComplexity), true - case "Query.User": + case "Query.user": if e.complexity.Query.User == nil { break } @@ -820,126 +820,126 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.User(childComplexity, args["id"].(int)), true - case "Query.Valid": + case "Query.valid": if e.complexity.Query.Valid == nil { break } return e.complexity.Query.Valid(childComplexity), true - case "Query.ValidType": + case "Query.validType": if e.complexity.Query.ValidType == nil { break } return e.complexity.Query.ValidType(childComplexity), true - case "Rectangle.Area": + case "Rectangle.area": if e.complexity.Rectangle.Area == nil { break } return e.complexity.Rectangle.Area(childComplexity), true - case "Rectangle.Length": + case "Rectangle.length": if e.complexity.Rectangle.Length == nil { break } return e.complexity.Rectangle.Length(childComplexity), true - case "Rectangle.Width": + case "Rectangle.width": if e.complexity.Rectangle.Width == nil { break } return e.complexity.Rectangle.Width(childComplexity), true - case "Slices.Test1": + case "Slices.test1": if e.complexity.Slices.Test1 == nil { break } return e.complexity.Slices.Test1(childComplexity), true - case "Slices.Test2": + case "Slices.test2": if e.complexity.Slices.Test2 == nil { break } return e.complexity.Slices.Test2(childComplexity), true - case "Slices.Test3": + case "Slices.test3": if e.complexity.Slices.Test3 == nil { break } return e.complexity.Slices.Test3(childComplexity), true - case "Slices.Test4": + case "Slices.test4": if e.complexity.Slices.Test4 == nil { break } return e.complexity.Slices.Test4(childComplexity), true - case "Subscription.InitPayload": + case "Subscription.initPayload": if e.complexity.Subscription.InitPayload == nil { break } return e.complexity.Subscription.InitPayload(childComplexity), true - case "Subscription.Updated": + case "Subscription.updated": if e.complexity.Subscription.Updated == nil { break } return e.complexity.Subscription.Updated(childComplexity), true - case "User.Created": + case "User.created": if e.complexity.User.Created == nil { break } return e.complexity.User.Created(childComplexity), true - case "User.Friends": + case "User.friends": if e.complexity.User.Friends == nil { break } return e.complexity.User.Friends(childComplexity), true - case "User.ID": + case "User.id": if e.complexity.User.ID == nil { break } return e.complexity.User.ID(childComplexity), true - case "User.Updated": + case "User.updated": if e.complexity.User.Updated == nil { break } return e.complexity.User.Updated(childComplexity), true - case "ValidType.DifferentCase": + case "ValidType.differentCase": if e.complexity.ValidType.DifferentCase == nil { break } return e.complexity.ValidType.DifferentCase(childComplexity), true - case "ValidType.DifferentCaseOld": + case "ValidType.different_case": if e.complexity.ValidType.DifferentCaseOld == nil { break } return e.complexity.ValidType.DifferentCaseOld(childComplexity), true - case "ValidType.ValidArgs": + case "ValidType.validArgs": if e.complexity.ValidType.ValidArgs == nil { break } @@ -951,7 +951,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ValidType.ValidArgs(childComplexity, args["break"].(string), args["default"].(string), args["func"].(string), args["interface"].(string), args["select"].(string), args["case"].(string), args["defer"].(string), args["go"].(string), args["map"].(string), args["struct"].(string), args["chan"].(string), args["else"].(string), args["goto"].(string), args["package"].(string), args["switch"].(string), args["const"].(string), args["fallthrough"].(string), args["if"].(string), args["range"].(string), args["type"].(string), args["continue"].(string), args["for"].(string), args["import"].(string), args["return"].(string), args["var"].(string), args["_"].(string)), true - case "ValidType.ValidInputKeywords": + case "ValidType.validInputKeywords": if e.complexity.ValidType.ValidInputKeywords == nil { break } @@ -963,28 +963,28 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.ValidType.ValidInputKeywords(childComplexity, args["input"].(*ValidInput)), true - case "XXIt.ID": + case "XXIt.id": if e.complexity.XXIt.ID == nil { break } return e.complexity.XXIt.ID(childComplexity), true - case "XxIt.ID": + case "XxIt.id": if e.complexity.XxIt.ID == nil { break } return e.complexity.XxIt.ID(childComplexity), true - case "asdfIt.ID": + case "asdfIt.id": if e.complexity.AsdfIt.ID == nil { break } return e.complexity.AsdfIt.ID(childComplexity), true - case "iIt.ID": + case "iIt.id": if e.complexity.IIt.ID == nil { break } diff --git a/example/chat/generated.go b/example/chat/generated.go index 9081ed4439b..47d9b7174d2 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -94,49 +94,49 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Chatroom.Messages": + case "Chatroom.messages": if e.complexity.Chatroom.Messages == nil { break } return e.complexity.Chatroom.Messages(childComplexity), true - case "Chatroom.Name": + case "Chatroom.name": if e.complexity.Chatroom.Name == nil { break } return e.complexity.Chatroom.Name(childComplexity), true - case "Message.CreatedAt": + case "Message.createdAt": if e.complexity.Message.CreatedAt == nil { break } return e.complexity.Message.CreatedAt(childComplexity), true - case "Message.CreatedBy": + case "Message.createdBy": if e.complexity.Message.CreatedBy == nil { break } return e.complexity.Message.CreatedBy(childComplexity), true - case "Message.ID": + case "Message.id": if e.complexity.Message.ID == nil { break } return e.complexity.Message.ID(childComplexity), true - case "Message.Text": + case "Message.text": if e.complexity.Message.Text == nil { break } return e.complexity.Message.Text(childComplexity), true - case "Mutation.Post": + case "Mutation.post": if e.complexity.Mutation.Post == nil { break } @@ -148,7 +148,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.Post(childComplexity, args["text"].(string), args["username"].(string), args["roomName"].(string)), true - case "Query.Room": + case "Query.room": if e.complexity.Query.Room == nil { break } @@ -160,7 +160,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Room(childComplexity, args["name"].(string)), true - case "Subscription.MessageAdded": + case "Subscription.messageAdded": if e.complexity.Subscription.MessageAdded == nil { break } diff --git a/example/config/generated.go b/example/config/generated.go index c95c8f1a063..053356645b8 100644 --- a/example/config/generated.go +++ b/example/config/generated.go @@ -89,7 +89,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Mutation.CreateTodo": + case "Mutation.createTodo": if e.complexity.Mutation.CreateTodo == nil { break } @@ -101,56 +101,56 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.CreateTodo(childComplexity, args["input"].(NewTodo)), true - case "Query.Todos": + case "Query.todos": if e.complexity.Query.Todos == nil { break } return e.complexity.Query.Todos(childComplexity), true - case "Todo.DatabaseID": + case "Todo.databaseId": if e.complexity.Todo.DatabaseID == nil { break } return e.complexity.Todo.DatabaseID(childComplexity), true - case "Todo.Description": + case "Todo.text": if e.complexity.Todo.Description == nil { break } return e.complexity.Todo.Description(childComplexity), true - case "Todo.Done": + case "Todo.done": if e.complexity.Todo.Done == nil { break } return e.complexity.Todo.Done(childComplexity), true - case "Todo.ID": + case "Todo.id": if e.complexity.Todo.ID == nil { break } return e.complexity.Todo.ID(childComplexity), true - case "Todo.User": + case "Todo.user": if e.complexity.Todo.User == nil { break } return e.complexity.Todo.User(childComplexity), true - case "User.FullName": + case "User.name": if e.complexity.User.FullName == nil { break } return e.complexity.User.FullName(childComplexity), true - case "User.ID": + case "User.id": if e.complexity.User.ID == nil { break } diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index ab15069c1a6..5260f2cf3f6 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -102,98 +102,98 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Address.Country": + case "Address.country": if e.complexity.Address.Country == nil { break } return e.complexity.Address.Country(childComplexity), true - case "Address.ID": + case "Address.id": if e.complexity.Address.ID == nil { break } return e.complexity.Address.ID(childComplexity), true - case "Address.Street": + case "Address.street": if e.complexity.Address.Street == nil { break } return e.complexity.Address.Street(childComplexity), true - case "Customer.Address": + case "Customer.address": if e.complexity.Customer.Address == nil { break } return e.complexity.Customer.Address(childComplexity), true - case "Customer.ID": + case "Customer.id": if e.complexity.Customer.ID == nil { break } return e.complexity.Customer.ID(childComplexity), true - case "Customer.Name": + case "Customer.name": if e.complexity.Customer.Name == nil { break } return e.complexity.Customer.Name(childComplexity), true - case "Customer.Orders": + case "Customer.orders": if e.complexity.Customer.Orders == nil { break } return e.complexity.Customer.Orders(childComplexity), true - case "Item.Name": + case "Item.name": if e.complexity.Item.Name == nil { break } return e.complexity.Item.Name(childComplexity), true - case "Order.Amount": + case "Order.amount": if e.complexity.Order.Amount == nil { break } return e.complexity.Order.Amount(childComplexity), true - case "Order.Date": + case "Order.date": if e.complexity.Order.Date == nil { break } return e.complexity.Order.Date(childComplexity), true - case "Order.ID": + case "Order.id": if e.complexity.Order.ID == nil { break } return e.complexity.Order.ID(childComplexity), true - case "Order.Items": + case "Order.items": if e.complexity.Order.Items == nil { break } return e.complexity.Order.Items(childComplexity), true - case "Query.Customers": + case "Query.customers": if e.complexity.Query.Customers == nil { break } return e.complexity.Query.Customers(childComplexity), true - case "Query.Torture1d": + case "Query.torture1d": if e.complexity.Query.Torture1d == nil { break } @@ -205,7 +205,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Torture1d(childComplexity, args["customerIds"].([]int)), true - case "Query.Torture2d": + case "Query.torture2d": if e.complexity.Query.Torture2d == nil { break } diff --git a/example/scalars/generated.go b/example/scalars/generated.go index e611828ae3e..7495cd71f0c 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -90,21 +90,21 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Address.ID": + case "Address.id": if e.complexity.Address.ID == nil { break } return e.complexity.Address.ID(childComplexity), true - case "Address.Location": + case "Address.location": if e.complexity.Address.Location == nil { break } return e.complexity.Address.Location(childComplexity), true - case "Query.Search": + case "Query.search": if e.complexity.Query.Search == nil { break } @@ -116,7 +116,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Search(childComplexity, args["input"].(*model.SearchArgs)), true - case "Query.User": + case "Query.user": if e.complexity.Query.User == nil { break } @@ -128,56 +128,56 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.User(childComplexity, args["id"].(external.ObjectID)), true - case "User.Address": + case "User.address": if e.complexity.User.Address == nil { break } return e.complexity.User.Address(childComplexity), true - case "User.Created": + case "User.created": if e.complexity.User.Created == nil { break } return e.complexity.User.Created(childComplexity), true - case "User.CustomResolver": + case "User.customResolver": if e.complexity.User.CustomResolver == nil { break } return e.complexity.User.CustomResolver(childComplexity), true - case "User.ID": + case "User.id": if e.complexity.User.ID == nil { break } return e.complexity.User.ID(childComplexity), true - case "User.IsBanned": + case "User.isBanned": if e.complexity.User.IsBanned == nil { break } return e.complexity.User.IsBanned(childComplexity), true - case "User.Name": + case "User.name": if e.complexity.User.Name == nil { break } return e.complexity.User.Name(childComplexity), true - case "User.PrimitiveResolver": + case "User.primitiveResolver": if e.complexity.User.PrimitiveResolver == nil { break } return e.complexity.User.PrimitiveResolver(childComplexity), true - case "User.Tier": + case "User.tier": if e.complexity.User.Tier == nil { break } diff --git a/example/selection/generated.go b/example/selection/generated.go index 18a99e88ba6..d1cea3817f9 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -80,63 +80,63 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Like.Collected": + case "Like.collected": if e.complexity.Like.Collected == nil { break } return e.complexity.Like.Collected(childComplexity), true - case "Like.Reaction": + case "Like.reaction": if e.complexity.Like.Reaction == nil { break } return e.complexity.Like.Reaction(childComplexity), true - case "Like.Selection": + case "Like.selection": if e.complexity.Like.Selection == nil { break } return e.complexity.Like.Selection(childComplexity), true - case "Like.Sent": + case "Like.sent": if e.complexity.Like.Sent == nil { break } return e.complexity.Like.Sent(childComplexity), true - case "Post.Collected": + case "Post.collected": if e.complexity.Post.Collected == nil { break } return e.complexity.Post.Collected(childComplexity), true - case "Post.Message": + case "Post.message": if e.complexity.Post.Message == nil { break } return e.complexity.Post.Message(childComplexity), true - case "Post.Selection": + case "Post.selection": if e.complexity.Post.Selection == nil { break } return e.complexity.Post.Selection(childComplexity), true - case "Post.Sent": + case "Post.sent": if e.complexity.Post.Sent == nil { break } return e.complexity.Post.Sent(childComplexity), true - case "Query.Events": + case "Query.events": if e.complexity.Query.Events == nil { break } diff --git a/example/starwars/generated/exec.go b/example/starwars/generated/exec.go index f31dcbe29b3..caba5a3fb4a 100644 --- a/example/starwars/generated/exec.go +++ b/example/starwars/generated/exec.go @@ -159,21 +159,21 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Droid.AppearsIn": + case "Droid.appearsIn": if e.complexity.Droid.AppearsIn == nil { break } return e.complexity.Droid.AppearsIn(childComplexity), true - case "Droid.Friends": + case "Droid.friends": if e.complexity.Droid.Friends == nil { break } return e.complexity.Droid.Friends(childComplexity), true - case "Droid.FriendsConnection": + case "Droid.friendsConnection": if e.complexity.Droid.FriendsConnection == nil { break } @@ -185,84 +185,84 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Droid.FriendsConnection(childComplexity, args["first"].(*int), args["after"].(*string)), true - case "Droid.ID": + case "Droid.id": if e.complexity.Droid.ID == nil { break } return e.complexity.Droid.ID(childComplexity), true - case "Droid.Name": + case "Droid.name": if e.complexity.Droid.Name == nil { break } return e.complexity.Droid.Name(childComplexity), true - case "Droid.PrimaryFunction": + case "Droid.primaryFunction": if e.complexity.Droid.PrimaryFunction == nil { break } return e.complexity.Droid.PrimaryFunction(childComplexity), true - case "FriendsConnection.Edges": + case "FriendsConnection.edges": if e.complexity.FriendsConnection.Edges == nil { break } return e.complexity.FriendsConnection.Edges(childComplexity), true - case "FriendsConnection.Friends": + case "FriendsConnection.friends": if e.complexity.FriendsConnection.Friends == nil { break } return e.complexity.FriendsConnection.Friends(childComplexity), true - case "FriendsConnection.PageInfo": + case "FriendsConnection.pageInfo": if e.complexity.FriendsConnection.PageInfo == nil { break } return e.complexity.FriendsConnection.PageInfo(childComplexity), true - case "FriendsConnection.TotalCount": + case "FriendsConnection.totalCount": if e.complexity.FriendsConnection.TotalCount == nil { break } return e.complexity.FriendsConnection.TotalCount(childComplexity), true - case "FriendsEdge.Cursor": + case "FriendsEdge.cursor": if e.complexity.FriendsEdge.Cursor == nil { break } return e.complexity.FriendsEdge.Cursor(childComplexity), true - case "FriendsEdge.Node": + case "FriendsEdge.node": if e.complexity.FriendsEdge.Node == nil { break } return e.complexity.FriendsEdge.Node(childComplexity), true - case "Human.AppearsIn": + case "Human.appearsIn": if e.complexity.Human.AppearsIn == nil { break } return e.complexity.Human.AppearsIn(childComplexity), true - case "Human.Friends": + case "Human.friends": if e.complexity.Human.Friends == nil { break } return e.complexity.Human.Friends(childComplexity), true - case "Human.FriendsConnection": + case "Human.friendsConnection": if e.complexity.Human.FriendsConnection == nil { break } @@ -274,7 +274,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Human.FriendsConnection(childComplexity, args["first"].(*int), args["after"].(*string)), true - case "Human.Height": + case "Human.height": if e.complexity.Human.Height == nil { break } @@ -286,35 +286,35 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Human.Height(childComplexity, args["unit"].(models.LengthUnit)), true - case "Human.ID": + case "Human.id": if e.complexity.Human.ID == nil { break } return e.complexity.Human.ID(childComplexity), true - case "Human.Mass": + case "Human.mass": if e.complexity.Human.Mass == nil { break } return e.complexity.Human.Mass(childComplexity), true - case "Human.Name": + case "Human.name": if e.complexity.Human.Name == nil { break } return e.complexity.Human.Name(childComplexity), true - case "Human.Starships": + case "Human.starships": if e.complexity.Human.Starships == nil { break } return e.complexity.Human.Starships(childComplexity), true - case "Mutation.CreateReview": + case "Mutation.createReview": if e.complexity.Mutation.CreateReview == nil { break } @@ -326,28 +326,28 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.CreateReview(childComplexity, args["episode"].(models.Episode), args["review"].(models.Review)), true - case "PageInfo.EndCursor": + case "PageInfo.endCursor": if e.complexity.PageInfo.EndCursor == nil { break } return e.complexity.PageInfo.EndCursor(childComplexity), true - case "PageInfo.HasNextPage": + case "PageInfo.hasNextPage": if e.complexity.PageInfo.HasNextPage == nil { break } return e.complexity.PageInfo.HasNextPage(childComplexity), true - case "PageInfo.StartCursor": + case "PageInfo.startCursor": if e.complexity.PageInfo.StartCursor == nil { break } return e.complexity.PageInfo.StartCursor(childComplexity), true - case "Query.Character": + case "Query.character": if e.complexity.Query.Character == nil { break } @@ -359,7 +359,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Character(childComplexity, args["id"].(string)), true - case "Query.Droid": + case "Query.droid": if e.complexity.Query.Droid == nil { break } @@ -371,7 +371,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Droid(childComplexity, args["id"].(string)), true - case "Query.Hero": + case "Query.hero": if e.complexity.Query.Hero == nil { break } @@ -383,7 +383,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Hero(childComplexity, args["episode"].(*models.Episode)), true - case "Query.Human": + case "Query.human": if e.complexity.Query.Human == nil { break } @@ -395,7 +395,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Human(childComplexity, args["id"].(string)), true - case "Query.Reviews": + case "Query.reviews": if e.complexity.Query.Reviews == nil { break } @@ -407,7 +407,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Reviews(childComplexity, args["episode"].(models.Episode), args["since"].(*time.Time)), true - case "Query.Search": + case "Query.search": if e.complexity.Query.Search == nil { break } @@ -419,7 +419,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Search(childComplexity, args["text"].(string)), true - case "Query.Starship": + case "Query.starship": if e.complexity.Query.Starship == nil { break } @@ -431,42 +431,42 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Starship(childComplexity, args["id"].(string)), true - case "Review.Commentary": + case "Review.commentary": if e.complexity.Review.Commentary == nil { break } return e.complexity.Review.Commentary(childComplexity), true - case "Review.Stars": + case "Review.stars": if e.complexity.Review.Stars == nil { break } return e.complexity.Review.Stars(childComplexity), true - case "Review.Time": + case "Review.time": if e.complexity.Review.Time == nil { break } return e.complexity.Review.Time(childComplexity), true - case "Starship.History": + case "Starship.history": if e.complexity.Starship.History == nil { break } return e.complexity.Starship.History(childComplexity), true - case "Starship.ID": + case "Starship.id": if e.complexity.Starship.ID == nil { break } return e.complexity.Starship.ID(childComplexity), true - case "Starship.Length": + case "Starship.length": if e.complexity.Starship.Length == nil { break } @@ -478,7 +478,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Starship.Length(childComplexity, args["unit"].(*models.LengthUnit)), true - case "Starship.Name": + case "Starship.name": if e.complexity.Starship.Name == nil { break } diff --git a/example/todo/generated.go b/example/todo/generated.go index 08ffac652d7..519f8781243 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -85,7 +85,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "MyMutation.CreateTodo": + case "MyMutation.createTodo": if e.complexity.MyMutation.CreateTodo == nil { break } @@ -97,7 +97,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MyMutation.CreateTodo(childComplexity, args["todo"].(TodoInput)), true - case "MyMutation.UpdateTodo": + case "MyMutation.updateTodo": if e.complexity.MyMutation.UpdateTodo == nil { break } @@ -109,14 +109,14 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MyMutation.UpdateTodo(childComplexity, args["id"].(int), args["changes"].(map[string]interface{})), true - case "MyQuery.LastTodo": + case "MyQuery.lastTodo": if e.complexity.MyQuery.LastTodo == nil { break } return e.complexity.MyQuery.LastTodo(childComplexity), true - case "MyQuery.Todo": + case "MyQuery.todo": if e.complexity.MyQuery.Todo == nil { break } @@ -128,28 +128,28 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MyQuery.Todo(childComplexity, args["id"].(int)), true - case "MyQuery.Todos": + case "MyQuery.todos": if e.complexity.MyQuery.Todos == nil { break } return e.complexity.MyQuery.Todos(childComplexity), true - case "Todo.Done": + case "Todo.done": if e.complexity.Todo.Done == nil { break } return e.complexity.Todo.Done(childComplexity), true - case "Todo.ID": + case "Todo.id": if e.complexity.Todo.ID == nil { break } return e.complexity.Todo.ID(childComplexity), true - case "Todo.Text": + case "Todo.text": if e.complexity.Todo.Text == nil { break } diff --git a/example/type-system-extension/generated.go b/example/type-system-extension/generated.go index d15500fd9f9..642b17b8c45 100644 --- a/example/type-system-extension/generated.go +++ b/example/type-system-extension/generated.go @@ -95,7 +95,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "MyMutation.CreateTodo": + case "MyMutation.createTodo": if e.complexity.MyMutation.CreateTodo == nil { break } @@ -107,7 +107,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MyMutation.CreateTodo(childComplexity, args["todo"].(TodoInput)), true - case "MyQuery.Todo": + case "MyQuery.todo": if e.complexity.MyQuery.Todo == nil { break } @@ -119,35 +119,35 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MyQuery.Todo(childComplexity, args["id"].(string)), true - case "MyQuery.Todos": + case "MyQuery.todos": if e.complexity.MyQuery.Todos == nil { break } return e.complexity.MyQuery.Todos(childComplexity), true - case "Todo.ID": + case "Todo.id": if e.complexity.Todo.ID == nil { break } return e.complexity.Todo.ID(childComplexity), true - case "Todo.State": + case "Todo.state": if e.complexity.Todo.State == nil { break } return e.complexity.Todo.State(childComplexity), true - case "Todo.Text": + case "Todo.text": if e.complexity.Todo.Text == nil { break } return e.complexity.Todo.Text(childComplexity), true - case "Todo.Verified": + case "Todo.verified": if e.complexity.Todo.Verified == nil { break } diff --git a/integration/generated.go b/integration/generated.go index 6b17e93743e..a92cdbaee6e 100644 --- a/integration/generated.go +++ b/integration/generated.go @@ -52,6 +52,7 @@ type ComplexityRoot struct { } Query struct { + Complexity func(childComplexity int, value int) int Date func(childComplexity int, filter models.DateFilter) int Error func(childComplexity int, typeArg *models.ErrorType) int JSONEncoding func(childComplexity int) int @@ -80,6 +81,7 @@ type QueryResolver interface { Viewer(ctx context.Context) (*models.Viewer, error) JSONEncoding(ctx context.Context) (string, error) Error(ctx context.Context, typeArg *models.ErrorType) (bool, error) + Complexity(ctx context.Context, value int) (bool, error) } type UserResolver interface { Likes(ctx context.Context, obj *remote_api.User) ([]string, error) @@ -100,28 +102,40 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in _ = ec switch typeName + "." + field { - case "Element.Child": + case "Element.child": if e.complexity.Element.Child == nil { break } return e.complexity.Element.Child(childComplexity), true - case "Element.Error": + case "Element.error": if e.complexity.Element.Error == nil { break } return e.complexity.Element.Error(childComplexity), true - case "Element.Mismatched": + case "Element.mismatched": if e.complexity.Element.Mismatched == nil { break } return e.complexity.Element.Mismatched(childComplexity), true - case "Query.Date": + case "Query.complexity": + if e.complexity.Query.Complexity == nil { + break + } + + args, err := ec.field_Query_complexity_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Query.Complexity(childComplexity, args["value"].(int)), true + + case "Query.date": if e.complexity.Query.Date == nil { break } @@ -133,7 +147,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Date(childComplexity, args["filter"].(models.DateFilter)), true - case "Query.Error": + case "Query.error": if e.complexity.Query.Error == nil { break } @@ -145,42 +159,42 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Error(childComplexity, args["type"].(*models.ErrorType)), true - case "Query.JSONEncoding": + case "Query.jsonEncoding": if e.complexity.Query.JSONEncoding == nil { break } return e.complexity.Query.JSONEncoding(childComplexity), true - case "Query.Path": + case "Query.path": if e.complexity.Query.Path == nil { break } return e.complexity.Query.Path(childComplexity), true - case "Query.Viewer": + case "Query.viewer": if e.complexity.Query.Viewer == nil { break } return e.complexity.Query.Viewer(childComplexity), true - case "User.Likes": + case "User.likes": if e.complexity.User.Likes == nil { break } return e.complexity.User.Likes(childComplexity), true - case "User.Name": + case "User.name": if e.complexity.User.Name == nil { break } return e.complexity.User.Name(childComplexity), true - case "Viewer.User": + case "Viewer.user": if e.complexity.Viewer.User == nil { break } @@ -306,6 +320,7 @@ type Query { viewer: Viewer jsonEncoding: String! error(type: ErrorType = NORMAL): Boolean! + complexity(value: Int!): Boolean! } enum ErrorType { @@ -354,6 +369,20 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs return args, nil } +func (ec *executionContext) field_Query_complexity_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 int + if tmp, ok := rawArgs["value"]; ok { + arg0, err = ec.unmarshalNInt2int(ctx, tmp) + if err != nil { + return nil, err + } + } + args["value"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query_date_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -635,6 +664,40 @@ func (ec *executionContext) _Query_error(ctx context.Context, field graphql.Coll return ec.marshalNBoolean2bool(ctx, field.Selections, res) } +func (ec *executionContext) _Query_complexity(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { + ctx = ec.Tracer.StartFieldExecution(ctx, field) + defer func() { ec.Tracer.EndFieldExecution(ctx) }() + rctx := &graphql.ResolverContext{ + Object: "Query", + Field: field, + Args: nil, + IsMethod: true, + } + ctx = graphql.WithResolverContext(ctx, rctx) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Query_complexity_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + rctx.Args = args + ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx) + resTmp := ec.FieldMiddleware(ctx, nil, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Query().Complexity(rctx, args["value"].(int)) + }) + if resTmp == nil { + if !ec.HasError(rctx) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + rctx.Result = res + ctx = ec.Tracer.StartFieldChildExecution(ctx) + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) graphql.Marshaler { ctx = ec.Tracer.StartFieldExecution(ctx, field) defer func() { ec.Tracer.EndFieldExecution(ctx) }() @@ -1784,6 +1847,20 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr } return res }) + case "complexity": + field := field + out.Concurrently(i, func() (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_complexity(ctx, field) + if res == graphql.Null { + invalid = true + } + return res + }) case "__type": out.Values[i] = ec._Query___type(ctx, field) case "__schema": @@ -2135,6 +2212,14 @@ func (ec *executionContext) marshalNElement2ᚖgithubᚗcomᚋ99designsᚋgqlgen return ec._Element(ctx, sel, v) } +func (ec *executionContext) unmarshalNInt2int(ctx context.Context, v interface{}) (int, error) { + return graphql.UnmarshalInt(v) +} + +func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.SelectionSet, v int) graphql.Marshaler { + return graphql.MarshalInt(v) +} + func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { return graphql.UnmarshalString(v) } diff --git a/integration/integration-test.js b/integration/integration-test.js index 43414ec17d0..948662efa82 100644 --- a/integration/integration-test.js +++ b/integration/integration-test.js @@ -43,6 +43,29 @@ describe('Input defaults', () => { }); }); +describe('Complexity', () => { + it('should fail when complexity is too high', async () => { + let res; + try { + res = await client.query({ + query: gql`{ complexity(value: 2000) }`, + }); + } catch (err) { + expect(err.networkError.statusCode).toEqual(422); + } + expect(res).toBe(undefined); + }); + + it('should succeed when complexity is not too high', async () => { + let res = await client.query({ + query: gql`{ complexity(value: 100) }`, + }); + + expect(res.data.complexity).toBe(true); + expect(res.errors).toBe(undefined); + }); +}); + describe('Errors', () => { it('should respond with correct paths', async () => { let res = await client.query({ diff --git a/integration/resolver.go b/integration/resolver.go index 5e685ceb196..7ed7353c8d7 100644 --- a/integration/resolver.go +++ b/integration/resolver.go @@ -91,6 +91,10 @@ func (r *queryResolver) JSONEncoding(ctx context.Context) (string, error) { return "\U000fe4ed", nil } +func (r *queryResolver) Complexity(ctx context.Context, value int) (bool, error) { + return true, nil +} + type userResolver struct{ *Resolver } func (r *userResolver) Likes(ctx context.Context, obj *remote_api.User) ([]string, error) { diff --git a/integration/schema-expected.graphql b/integration/schema-expected.graphql index 52e5308faff..456bd25230e 100644 --- a/integration/schema-expected.graphql +++ b/integration/schema-expected.graphql @@ -36,6 +36,7 @@ type Query { viewer: Viewer jsonEncoding: String! error(type: ErrorType = NORMAL): Boolean! + complexity(value: Int!): Boolean! } type User { diff --git a/integration/schema.graphql b/integration/schema.graphql index ac2df27bed7..73acb7278d2 100644 --- a/integration/schema.graphql +++ b/integration/schema.graphql @@ -35,6 +35,7 @@ type Query { viewer: Viewer jsonEncoding: String! error(type: ErrorType = NORMAL): Boolean! + complexity(value: Int!): Boolean! } enum ErrorType { diff --git a/integration/server/server.go b/integration/server/server.go index f17ed2ada91..63e31b96e45 100644 --- a/integration/server/server.go +++ b/integration/server/server.go @@ -21,9 +21,15 @@ func main() { port = defaultPort } + cfg := integration.Config{Resolvers: &integration.Resolver{}} + cfg.Complexity.Query.Complexity = func(childComplexity, value int) int { + // Allow the integration client to dictate the complexity, to verify this + // function is executed. + return value + } http.Handle("/", handler.Playground("GraphQL playground", "/query")) http.Handle("/query", handler.GraphQL( - integration.NewExecutableSchema(integration.Config{Resolvers: &integration.Resolver{}}), + integration.NewExecutableSchema(cfg), handler.ErrorPresenter(func(ctx context.Context, e error) *gqlerror.Error { if e, ok := errors.Cause(e).(*integration.CustomError); ok { return &gqlerror.Error{ @@ -33,6 +39,7 @@ func main() { } return graphql.DefaultErrorPresenter(ctx, e) }), + handler.ComplexityLimit(1000), )) log.Printf("connect to http://localhost:%s/ for GraphQL playground", port)