Skip to content

Add context throughout graphql #25

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 23 additions & 22 deletions executor/abstract_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"github.com/chris-ramon/graphql-go/language/location"
"github.com/chris-ramon/graphql-go/testutil"
"github.com/chris-ramon/graphql-go/types"
"golang.org/x/net/context"
"reflect"
"testing"
)
Expand Down Expand Up @@ -48,7 +49,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Name
}
Expand All @@ -57,7 +58,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {
},
"woofs": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Woofs
}
Expand All @@ -79,7 +80,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Name
}
Expand All @@ -88,7 +89,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {
},
"meows": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Meows
}
Expand All @@ -103,7 +104,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForInterface(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"pets": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(petType),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return []interface{}{
&testDog{"Odie", true},
&testCat{"Garfield", false},
Expand Down Expand Up @@ -171,7 +172,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Name
}
Expand All @@ -180,7 +181,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {
},
"woofs": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Woofs
}
Expand All @@ -198,7 +199,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Name
}
Expand All @@ -207,7 +208,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {
},
"meows": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Meows
}
Expand Down Expand Up @@ -238,7 +239,7 @@ func TestIsTypeOfUsedToResolveRuntimeTypeForUnion(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"pets": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(petType),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return []interface{}{
&testDog{"Odie", true},
&testCat{"Garfield", false},
Expand Down Expand Up @@ -327,7 +328,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if human, ok := p.Source.(*testHuman); ok {
return human.Name
}
Expand All @@ -348,7 +349,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Name
}
Expand All @@ -357,7 +358,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
},
"woofs": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Woofs
}
Expand All @@ -378,7 +379,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Name
}
Expand All @@ -387,7 +388,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
},
"meows": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Meows
}
Expand All @@ -402,7 +403,7 @@ func TestResolveTypeOnInterfaceYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"pets": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(petType),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return []interface{}{
&testDog{"Odie", true},
&testCat{"Garfield", false},
Expand Down Expand Up @@ -473,7 +474,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if human, ok := p.Source.(*testHuman); ok {
return human.Name
}
Expand All @@ -491,7 +492,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Name
}
Expand All @@ -500,7 +501,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
},
"woofs": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if dog, ok := p.Source.(*testDog); ok {
return dog.Woofs
}
Expand All @@ -518,7 +519,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"name": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Name
}
Expand All @@ -527,7 +528,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
},
"meows": &types.GraphQLFieldConfig{
Type: types.GraphQLBoolean,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if cat, ok := p.Source.(*testCat); ok {
return cat.Meows
}
Expand Down Expand Up @@ -560,7 +561,7 @@ func TestResolveTypeOnUnionYieldsUsefulError(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"pets": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(petType),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return []interface{}{
&testDog{"Odie", true},
&testCat{"Garfield", false},
Expand Down
10 changes: 8 additions & 2 deletions executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import (
"github.com/chris-ramon/graphql-go/errors"
"github.com/chris-ramon/graphql-go/language/ast"
"github.com/chris-ramon/graphql-go/types"
"golang.org/x/net/context"
"reflect"
"strings"
)

type ExecuteParams struct {
Schema types.GraphQLSchema
Root interface{}
Ctx context.Context
AST *ast.Document
OperationName string
Args map[string]interface{}
Expand All @@ -25,6 +27,7 @@ func Execute(p ExecuteParams, resultChan chan *types.GraphQLResult) {
Schema: p.Schema,
Root: p.Root,
AST: p.AST,
Ctx: p.Ctx,
OperationName: p.OperationName,
Args: p.Args,
Errors: errors,
Expand Down Expand Up @@ -58,6 +61,7 @@ type BuildExecutionCtxParams struct {
Schema types.GraphQLSchema
Root interface{}
AST *ast.Document
Ctx context.Context
OperationName string
Args map[string]interface{}
Errors []graphqlerrors.GraphQLFormattedError
Expand All @@ -66,6 +70,7 @@ type BuildExecutionCtxParams struct {
}
type ExecutionContext struct {
Schema types.GraphQLSchema
Ctx context.Context
Fragments map[string]ast.Definition
Root interface{}
Operation ast.Definition
Expand Down Expand Up @@ -129,6 +134,7 @@ func buildExecutionContext(p BuildExecutionCtxParams) *ExecutionContext {
}

eCtx.Schema = p.Schema
eCtx.Ctx = p.Ctx
eCtx.Fragments = fragments
eCtx.Root = p.Root
eCtx.Operation = operation
Expand Down Expand Up @@ -516,7 +522,7 @@ func resolveField(eCtx *ExecutionContext, parentType *types.GraphQLObjectType, s
// it is wrapped as a GraphQLError with locations. Log this error and return
// null if allowed, otherwise throw the error so the parent field can handle
// it.
result = resolveFn(types.GQLFRParams{
result = resolveFn(eCtx.Ctx, types.GQLFRParams{
Source: source,
Args: args,
Info: info,
Expand Down Expand Up @@ -692,7 +698,7 @@ func completeValue(eCtx *ExecutionContext, returnType types.GraphQLType, fieldAS

}

func defaultResolveFn(p types.GQLFRParams) interface{} {
func defaultResolveFn(ctx context.Context, p types.GQLFRParams) interface{} {
// try to resolve p.Source as a struct first
sourceVal := reflect.ValueOf(p.Source)
if sourceVal.IsValid() && sourceVal.Type().Kind() == reflect.Ptr {
Expand Down
7 changes: 4 additions & 3 deletions executor/executor_schema_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"github.com/chris-ramon/graphql-go/executor"
"github.com/chris-ramon/graphql-go/testutil"
"github.com/chris-ramon/graphql-go/types"
"golang.org/x/net/context"
"reflect"
"testing"
)
Expand Down Expand Up @@ -106,7 +107,7 @@ func TestExecutesUsingAComplexSchema(t *testing.T) {
Type: types.GraphQLInt,
},
},
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
if author, ok := p.Source.(*testAuthor); ok {
width := fmt.Sprintf("%v", p.Args["width"])
height := fmt.Sprintf("%v", p.Args["height"])
Expand Down Expand Up @@ -156,14 +157,14 @@ func TestExecutesUsingAComplexSchema(t *testing.T) {
Type: types.GraphQLID,
},
},
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
id := p.Args["id"]
return article(id)
},
},
"feed": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(blogArticle),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return []*testArticle{
article(1),
article(2),
Expand Down
21 changes: 11 additions & 10 deletions executor/executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/chris-ramon/graphql-go/language/location"
"github.com/chris-ramon/graphql-go/testutil"
"github.com/chris-ramon/graphql-go/types"
"golang.org/x/net/context"
"reflect"
"testing"
)
Expand Down Expand Up @@ -103,7 +104,7 @@ func TestExecutesArbitraryCode(t *testing.T) {
}

// Schema Definitions
picResolverFn := func(p types.GQLFRParams) interface{} {
picResolverFn := func(ctx context.Context, p types.GQLFRParams) interface{} {
// get and type assert ResolveFn for this field
picResolver, ok := p.Source.(map[string]interface{})["pic"].(func(size int) string)
if !ok {
Expand Down Expand Up @@ -244,27 +245,27 @@ func TestMergesParallelFragments(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"a": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return "Apple"
},
},
"b": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return "Banana"
},
},
"c": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return "Cherry"
},
},
},
})
deepTypeFieldConfig := &types.GraphQLFieldConfig{
Type: typeObjectType,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return p.Source
},
}
Expand Down Expand Up @@ -312,7 +313,7 @@ func TestThreadsContextCorrectly(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"a": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
resolvedContext = p.Source.(map[string]interface{})
return resolvedContext
},
Expand Down Expand Up @@ -368,7 +369,7 @@ func TestCorrectlyThreadsArguments(t *testing.T) {
},
},
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
resolvedArgs = p.Args
return resolvedArgs
},
Expand Down Expand Up @@ -944,7 +945,7 @@ func TestDoesNotIncludeArgumentsThatWereNotSet(t *testing.T) {
Type: types.GraphQLInt,
},
},
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
args, _ := json.Marshal(p.Args)
return string(args)
},
Expand Down Expand Up @@ -1019,7 +1020,7 @@ func TestFailsWhenAnIsTypeOfCheckIsNotMet(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"value": &types.GraphQLFieldConfig{
Type: types.GraphQLString,
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return p.Source.(testSpecialType).Value
},
},
Expand All @@ -1031,7 +1032,7 @@ func TestFailsWhenAnIsTypeOfCheckIsNotMet(t *testing.T) {
Fields: types.GraphQLFieldConfigMap{
"specials": &types.GraphQLFieldConfig{
Type: types.NewGraphQLList(specialType),
Resolve: func(p types.GQLFRParams) interface{} {
Resolve: func(ctx context.Context, p types.GQLFRParams) interface{} {
return p.Source.(map[string]interface{})["specials"]
},
},
Expand Down
Loading