Skip to content

Commit

Permalink
Use struct fields as resolvers instead of methods (graph-gophers#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
Salman Ahmad committed Apr 11, 2018
1 parent 00d3035 commit 95f2b85
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 78 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/internal/validation/testdata/graphql-js
/internal/validation/testdata/node_modules
/vendor
.DS_Store
.idea/
.vscode/
11 changes: 11 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package config

type Config struct {
UseResolverMethods bool
}

func Default() *Config {
return &Config{
UseResolverMethods: true,
}
}
2 changes: 1 addition & 1 deletion example/starwars/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
var schema *graphql.Schema

func init() {
schema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{})
schema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{}, nil)
}

func main() {
Expand Down
3 changes: 1 addition & 2 deletions graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package graphql

import (
"context"
"fmt"

"encoding/json"
"fmt"

"github.com/graph-gophers/graphql-go/errors"
"github.com/graph-gophers/graphql-go/internal/common"
Expand Down
28 changes: 14 additions & 14 deletions graphql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func (r *timeResolver) AddHour(args struct{ Time graphql.Time }) graphql.Time {
return graphql.Time{Time: args.Time.Add(time.Hour)}
}

var starwarsSchema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{})
var starwarsSchema = graphql.MustParseSchema(starwars.Schema, &starwars.Resolver{}, nil)

func TestHelloWorld(t *testing.T) {
gqltesting.RunTests(t, []*gqltesting.Test{
Expand All @@ -74,7 +74,7 @@ func TestHelloWorld(t *testing.T) {
type Query {
hello: String!
}
`, &helloWorldResolver1{}),
`, &helloWorldResolver1{}, nil),
Query: `
{
hello
Expand All @@ -96,7 +96,7 @@ func TestHelloWorld(t *testing.T) {
type Query {
hello: String!
}
`, &helloWorldResolver2{}),
`, &helloWorldResolver2{}, nil),
Query: `
{
hello
Expand All @@ -122,7 +122,7 @@ func TestHelloSnake(t *testing.T) {
type Query {
hello_html: String!
}
`, &helloSnakeResolver1{}),
`, &helloSnakeResolver1{}, nil),
Query: `
{
hello_html
Expand All @@ -144,7 +144,7 @@ func TestHelloSnake(t *testing.T) {
type Query {
hello_html: String!
}
`, &helloSnakeResolver2{}),
`, &helloSnakeResolver2{}, nil),
Query: `
{
hello_html
Expand All @@ -170,7 +170,7 @@ func TestHelloSnakeArguments(t *testing.T) {
type Query {
say_hello(full_name: String!): String!
}
`, &helloSnakeResolver1{}),
`, &helloSnakeResolver1{}, nil),
Query: `
{
say_hello(full_name: "Rob Pike")
Expand All @@ -192,7 +192,7 @@ func TestHelloSnakeArguments(t *testing.T) {
type Query {
say_hello(full_name: String!): String!
}
`, &helloSnakeResolver2{}),
`, &helloSnakeResolver2{}, nil),
Query: `
{
say_hello(full_name: "Rob Pike")
Expand Down Expand Up @@ -606,7 +606,7 @@ func TestDeprecatedDirective(t *testing.T) {
b: Int! @deprecated
c: Int! @deprecated(reason: "We don't like it")
}
`, &testDeprecatedDirectiveResolver{}),
`, &testDeprecatedDirectiveResolver{}, nil),
Query: `
{
__type(name: "Query") {
Expand Down Expand Up @@ -650,7 +650,7 @@ func TestDeprecatedDirective(t *testing.T) {
B @deprecated
C @deprecated(reason: "We don't like it")
}
`, &testDeprecatedDirectiveResolver{}),
`, &testDeprecatedDirectiveResolver{}, nil),
Query: `
{
__type(name: "Test") {
Expand Down Expand Up @@ -1441,7 +1441,7 @@ func TestMutationOrder(t *testing.T) {
type Mutation {
changeTheNumber(newNumber: Int!): Query
}
`, &theNumberResolver{}),
`, &theNumberResolver{}, nil),
Query: `
mutation {
first: changeTheNumber(newNumber: 1) {
Expand Down Expand Up @@ -1485,7 +1485,7 @@ func TestTime(t *testing.T) {
}
scalar Time
`, &timeResolver{}),
`, &timeResolver{}, nil),
Query: `
query($t: Time!) {
a: addHour(time: $t)
Expand Down Expand Up @@ -1520,7 +1520,7 @@ func TestUnexportedMethod(t *testing.T) {
type Mutation {
changeTheNumber(newNumber: Int!): Int!
}
`, &resolverWithUnexportedMethod{})
`, &resolverWithUnexportedMethod{}, nil)
if err == nil {
t.Error("error expected")
}
Expand All @@ -1541,7 +1541,7 @@ func TestUnexportedField(t *testing.T) {
type Mutation {
changeTheNumber(newNumber: Int!): Int!
}
`, &resolverWithUnexportedField{})
`, &resolverWithUnexportedField{}, nil)
if err == nil {
t.Error("error expected")
}
Expand Down Expand Up @@ -1648,7 +1648,7 @@ func TestInput(t *testing.T) {
Option1
Option2
}
`, &inputResolver{})
`, &inputResolver{}, nil)
gqltesting.RunTests(t, []*gqltesting.Test{
{
Schema: coercionSchema,
Expand Down
37 changes: 21 additions & 16 deletions internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,22 +173,28 @@ func execFieldSelection(ctx context.Context, r *Request, f *fieldToExec, path *p
return errors.Errorf("%s", err) // don't execute any more resolvers if context got cancelled
}

var in []reflect.Value
if f.field.HasContext {
in = append(in, reflect.ValueOf(traceCtx))
}
if f.field.ArgsPacker != nil {
in = append(in, f.field.PackedArgs)
}
callOut := f.resolver.Method(f.field.MethodIndex).Call(in)
result = callOut[0]
if f.field.HasError && !callOut[1].IsNil() {
resolverErr := callOut[1].Interface().(error)
err := errors.Errorf("%s", resolverErr)
err.Path = path.toSlice()
err.ResolverError = resolverErr
return err
if f.field.MethodIndex != -1 {
var in []reflect.Value
if f.field.HasContext {
in = append(in, reflect.ValueOf(traceCtx))
}
if f.field.ArgsPacker != nil {
in = append(in, f.field.PackedArgs)
}

callOut := f.resolver.Method(f.field.MethodIndex).Call(in)
result = callOut[0]
if f.field.HasError && !callOut[1].IsNil() {
resolverErr := callOut[1].Interface().(error)
err := errors.Errorf("%s", resolverErr)
err.Path = path.toSlice()
err.ResolverError = resolverErr
return err
}
} else {
result = f.resolver.Field(f.field.FieldIndex)
}

return nil
}()

Expand All @@ -201,7 +207,6 @@ func execFieldSelection(ctx context.Context, r *Request, f *fieldToExec, path *p
f.out.WriteString("null") // TODO handle non-nil
return
}

r.execSelectionSet(traceCtx, f.sels, f.field.Type, path, result, f.out)
}

Expand Down
Loading

0 comments on commit 95f2b85

Please sign in to comment.