From 1ba61fcb262123cefb506c899160292fc1dab542 Mon Sep 17 00:00:00 2001 From: creativej Date: Mon, 23 Jul 2018 13:26:53 +1000 Subject: [PATCH] Update test & examples to use new resolver pattern * chat * dataloader * scalar * selection * starwars * todo --- example/chat/chat_test.go | 2 +- example/chat/generated.go | 40 ++------ example/chat/resolvers.go | 34 +++++-- example/chat/server/server.go | 2 +- example/dataloader/dataloader_test.go | 2 +- example/dataloader/generated.go | 54 ++--------- example/dataloader/resolvers.go | 34 +++++-- example/dataloader/server/server.go | 2 +- example/scalars/generated.go | 47 ++------- example/scalars/resolvers.go | 20 +++- example/scalars/scalar_test.go | 2 +- example/scalars/server/server.go | 2 +- example/selection/generated.go | 25 +---- example/selection/selection.go | 10 +- example/selection/selection_test.go | 2 +- example/selection/server/server.go | 2 +- example/starwars/generated.go | 135 ++++---------------------- example/starwars/resolvers.go | 120 +++++++++++++++-------- example/starwars/server/server.go | 2 +- example/starwars/starwars_test.go | 2 +- example/todo/generated.go | 53 ++-------- test/generated.go | 75 +++----------- test/resolvers_test.go | 60 ++++++++---- 23 files changed, 267 insertions(+), 460 deletions(-) diff --git a/example/chat/chat_test.go b/example/chat/chat_test.go index 4b63fd0526c..409edf2db4d 100644 --- a/example/chat/chat_test.go +++ b/example/chat/chat_test.go @@ -10,7 +10,7 @@ import ( ) func TestChat(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(New()))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(New()))) c := client.New(srv.URL) t.Run("subscribe to chat events", func(t *testing.T) { diff --git a/example/chat/generated.go b/example/chat/generated.go index a78511caf40..ddc98dd012c 100644 --- a/example/chat/generated.go +++ b/example/chat/generated.go @@ -13,21 +13,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Mutation_post(ctx context.Context, text string, username string, roomName string) (Message, error) - Query_room(ctx context.Context, name string) (*Chatroom, error) - - Subscription_messageAdded(ctx context.Context, roomName string) (<-chan Message, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -45,24 +33,8 @@ type SubscriptionResolver interface { MessageAdded(ctx context.Context, roomName string) (<-chan Message, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Mutation_post(ctx context.Context, text string, username string, roomName string) (Message, error) { - return s.r.Mutation().Post(ctx, text, username, roomName) -} - -func (s shortMapper) Query_room(ctx context.Context, name string) (*Chatroom, error) { - return s.r.Query().Room(ctx, name) -} - -func (s shortMapper) Subscription_messageAdded(ctx context.Context, roomName string) (<-chan Message, error) { - return s.r.Subscription().MessageAdded(ctx, roomName) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -132,7 +104,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var chatroomImplementors = []string{"Chatroom"} @@ -330,7 +302,7 @@ func (ec *executionContext) _Mutation_post(ctx context.Context, field graphql.Co rctx.PushField(field.Alias) defer rctx.Pop() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Mutation_post(ctx, args["text"].(string), args["username"].(string), args["roomName"].(string)) + return ec.resolvers.Mutation().Post(ctx, args["text"].(string), args["username"].(string), args["roomName"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -401,7 +373,7 @@ func (ec *executionContext) _Query_room(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_room(ctx, args["name"].(string)) + return ec.resolvers.Query().Room(ctx, args["name"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -491,7 +463,7 @@ func (ec *executionContext) _Subscription_messageAdded(ctx context.Context, fiel } args["roomName"] = arg0 ctx = graphql.WithResolverContext(ctx, &graphql.ResolverContext{Field: field}) - results, err := ec.resolvers.Subscription_messageAdded(ctx, args["roomName"].(string)) + results, err := ec.resolvers.Subscription().MessageAdded(ctx, args["roomName"].(string)) if err != nil { ec.Error(ctx, err) return nil diff --git a/example/chat/resolvers.go b/example/chat/resolvers.go index 6bbb0a60dc6..f9f8ee3f083 100644 --- a/example/chat/resolvers.go +++ b/example/chat/resolvers.go @@ -9,13 +9,25 @@ import ( "time" ) -type resolvers struct { +type resolver struct { Rooms map[string]*Chatroom - mu sync.Mutex + mu sync.Mutex // nolint: structcheck } -func New() *resolvers { - return &resolvers{ +func (r *resolver) Mutation() MutationResolver { + return &mutationResolver{r} +} + +func (r *resolver) Query() QueryResolver { + return &queryResolver{r} +} + +func (r *resolver) Subscription() SubscriptionResolver { + return &subscriptionResolver{r} +} + +func New() *resolver { + return &resolver{ Rooms: map[string]*Chatroom{}, } } @@ -26,7 +38,9 @@ type Chatroom struct { Observers map[string]chan Message } -func (r *resolvers) Mutation_post(ctx context.Context, text string, userName string, roomName string) (Message, error) { +type mutationResolver struct{ *resolver } + +func (r *mutationResolver) Post(ctx context.Context, text string, username string, roomName string) (Message, error) { r.mu.Lock() room := r.Rooms[roomName] if room == nil { @@ -39,7 +53,7 @@ func (r *resolvers) Mutation_post(ctx context.Context, text string, userName str ID: randString(8), CreatedAt: time.Now(), Text: text, - CreatedBy: userName, + CreatedBy: username, } room.Messages = append(room.Messages, message) @@ -51,7 +65,9 @@ func (r *resolvers) Mutation_post(ctx context.Context, text string, userName str return message, nil } -func (r *resolvers) Query_room(ctx context.Context, name string) (*Chatroom, error) { +type queryResolver struct{ *resolver } + +func (r *queryResolver) Room(ctx context.Context, name string) (*Chatroom, error) { r.mu.Lock() room := r.Rooms[name] if room == nil { @@ -63,7 +79,9 @@ func (r *resolvers) Query_room(ctx context.Context, name string) (*Chatroom, err return room, nil } -func (r *resolvers) Subscription_messageAdded(ctx context.Context, roomName string) (<-chan Message, error) { +type subscriptionResolver struct{ *resolver } + +func (r *subscriptionResolver) MessageAdded(ctx context.Context, roomName string) (<-chan Message, error) { r.mu.Lock() room := r.Rooms[roomName] if room == nil { diff --git a/example/chat/server/server.go b/example/chat/server/server.go index 1a163996378..6bb56ea98b4 100644 --- a/example/chat/server/server.go +++ b/example/chat/server/server.go @@ -20,7 +20,7 @@ func main() { startAppdashServer() http.Handle("/", handler.Playground("Todo", "/query")) - http.Handle("/query", handler.GraphQL(chat.MakeExecutableSchema(chat.New()), + http.Handle("/query", handler.GraphQL(chat.NewExecutableSchema(chat.New()), handler.ResolverMiddleware(gqlopentracing.ResolverMiddleware()), handler.RequestMiddleware(gqlopentracing.RequestMiddleware()), handler.WebsocketUpgrader(websocket.Upgrader{ diff --git a/example/dataloader/dataloader_test.go b/example/dataloader/dataloader_test.go index c10bb574724..4948feacc48 100644 --- a/example/dataloader/dataloader_test.go +++ b/example/dataloader/dataloader_test.go @@ -11,7 +11,7 @@ import ( ) func TestTodo(t *testing.T) { - srv := httptest.NewServer(LoaderMiddleware(handler.GraphQL(MakeExecutableSchema(&Resolver{})))) + srv := httptest.NewServer(LoaderMiddleware(handler.GraphQL(NewExecutableSchema(&Resolver{})))) c := client.New(srv.URL) t.Run("create a new todo", func(t *testing.T) { diff --git a/example/dataloader/generated.go b/example/dataloader/generated.go index 7695566c644..fff48520fd6 100644 --- a/example/dataloader/generated.go +++ b/example/dataloader/generated.go @@ -13,23 +13,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Customer_address(ctx context.Context, obj *Customer) (*Address, error) - Customer_orders(ctx context.Context, obj *Customer) ([]Order, error) - - Order_items(ctx context.Context, obj *Order) ([]Item, error) - Query_customers(ctx context.Context) ([]Customer, error) - Query_torture(ctx context.Context, customerIds [][]int) ([][]Customer, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -49,32 +35,8 @@ type QueryResolver interface { Torture(ctx context.Context, customerIds [][]int) ([][]Customer, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Customer_address(ctx context.Context, obj *Customer) (*Address, error) { - return s.r.Customer().Address(ctx, obj) -} - -func (s shortMapper) Customer_orders(ctx context.Context, obj *Customer) ([]Order, error) { - return s.r.Customer().Orders(ctx, obj) -} - -func (s shortMapper) Order_items(ctx context.Context, obj *Order) ([]Item, error) { - return s.r.Order().Items(ctx, obj) -} - -func (s shortMapper) Query_customers(ctx context.Context) ([]Customer, error) { - return s.r.Query().Customers(ctx) -} - -func (s shortMapper) Query_torture(ctx context.Context, customerIds [][]int) ([][]Customer, error) { - return s.r.Query().Torture(ctx, customerIds) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -108,7 +70,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var addressImplementors = []string{"Address"} @@ -238,7 +200,7 @@ func (ec *executionContext) _Customer_address(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Customer_address(ctx, obj) + return ec.resolvers.Customer().Address(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -271,7 +233,7 @@ func (ec *executionContext) _Customer_orders(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Customer_orders(ctx, obj) + return ec.resolvers.Customer().Orders(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -406,7 +368,7 @@ func (ec *executionContext) _Order_items(ctx context.Context, field graphql.Coll }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Order_items(ctx, obj) + return ec.resolvers.Order().Items(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -478,7 +440,7 @@ func (ec *executionContext) _Query_customers(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_customers(ctx) + return ec.resolvers.Query().Customers(ctx) }) if err != nil { ec.Error(ctx, err) @@ -546,7 +508,7 @@ func (ec *executionContext) _Query_torture(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_torture(ctx, args["customerIds"].([][]int)) + return ec.resolvers.Query().Torture(ctx, args["customerIds"].([][]int)) }) if err != nil { ec.Error(ctx, err) diff --git a/example/dataloader/resolvers.go b/example/dataloader/resolvers.go index 2bd93c95ba5..77765e03bb4 100644 --- a/example/dataloader/resolvers.go +++ b/example/dataloader/resolvers.go @@ -22,19 +22,37 @@ type Order struct { type Resolver struct{} -func (r *Resolver) Customer_address(ctx context.Context, it *Customer) (*Address, error) { - return ctxLoaders(ctx).addressByID.Load(it.AddressID) +func (r *Resolver) Customer() CustomerResolver { + return &customerResolver{r} } -func (r *Resolver) Customer_orders(ctx context.Context, it *Customer) ([]Order, error) { - return ctxLoaders(ctx).ordersByCustomer.Load(it.ID) +func (r *Resolver) Order() OrderResolver { + return &orderResolver{r} } -func (r *Resolver) Order_items(ctx context.Context, it *Order) ([]Item, error) { - return ctxLoaders(ctx).itemsByOrder.Load(it.ID) +func (r *Resolver) Query() QueryResolver { + return &queryResolver{r} } -func (r *Resolver) Query_customers(ctx context.Context) ([]Customer, error) { +type customerResolver struct{ *Resolver } + +func (r *customerResolver) Address(ctx context.Context, obj *Customer) (*Address, error) { + return ctxLoaders(ctx).addressByID.Load(obj.AddressID) +} + +func (r *customerResolver) Orders(ctx context.Context, obj *Customer) ([]Order, error) { + return ctxLoaders(ctx).ordersByCustomer.Load(obj.ID) +} + +type orderResolver struct{ *Resolver } + +func (r *orderResolver) Items(ctx context.Context, obj *Order) ([]Item, error) { + return ctxLoaders(ctx).itemsByOrder.Load(obj.ID) +} + +type queryResolver struct{ *Resolver } + +func (r *queryResolver) Customers(ctx context.Context) ([]Customer, error) { fmt.Println("SELECT * FROM customer") time.Sleep(5 * time.Millisecond) @@ -47,7 +65,7 @@ func (r *Resolver) Query_customers(ctx context.Context) ([]Customer, error) { } // this method is here to test code generation of nested arrays -func (r *Resolver) Query_torture(ctx context.Context, customerIds [][]int) ([][]Customer, error) { +func (r *queryResolver) Torture(ctx context.Context, customerIds [][]int) ([][]Customer, error) { result := make([][]Customer, len(customerIds)) for i := range customerIds { inner := make([]Customer, len(customerIds[i])) diff --git a/example/dataloader/server/server.go b/example/dataloader/server/server.go index 22b3b214e51..5f1a501fa4a 100644 --- a/example/dataloader/server/server.go +++ b/example/dataloader/server/server.go @@ -26,7 +26,7 @@ func main() { router.Handle("/", handler.Playground("Dataloader", "/query")) router.Handle("/query", handler.GraphQL( - dataloader.MakeExecutableSchema(&dataloader.Resolver{}), + dataloader.NewExecutableSchema(&dataloader.Resolver{}), handler.ResolverMiddleware(gqlopentracing.ResolverMiddleware()), handler.RequestMiddleware(gqlopentracing.RequestMiddleware()), )) diff --git a/example/scalars/generated.go b/example/scalars/generated.go index c9c6314c804..93b6b50910d 100644 --- a/example/scalars/generated.go +++ b/example/scalars/generated.go @@ -16,22 +16,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Query_user(ctx context.Context, id external.ObjectID) (*model.User, error) - Query_search(ctx context.Context, input model.SearchArgs) ([]model.User, error) - - User_primitiveResolver(ctx context.Context, obj *model.User) (string, error) - User_customResolver(ctx context.Context, obj *model.User) (model.Point, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -47,28 +34,8 @@ type UserResolver interface { CustomResolver(ctx context.Context, obj *model.User) (model.Point, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Query_user(ctx context.Context, id external.ObjectID) (*model.User, error) { - return s.r.Query().User(ctx, id) -} - -func (s shortMapper) Query_search(ctx context.Context, input model.SearchArgs) ([]model.User, error) { - return s.r.Query().Search(ctx, input) -} - -func (s shortMapper) User_primitiveResolver(ctx context.Context, obj *model.User) (string, error) { - return s.r.User().PrimitiveResolver(ctx, obj) -} - -func (s shortMapper) User_customResolver(ctx context.Context, obj *model.User) (model.Point, error) { - return s.r.User().CustomResolver(ctx, obj) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -102,7 +69,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var addressImplementors = []string{"Address"} @@ -215,7 +182,7 @@ func (ec *executionContext) _Query_user(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_user(ctx, args["id"].(external.ObjectID)) + return ec.resolvers.Query().User(ctx, args["id"].(external.ObjectID)) }) if err != nil { ec.Error(ctx, err) @@ -268,7 +235,7 @@ func (ec *executionContext) _Query_search(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_search(ctx, args["input"].(model.SearchArgs)) + return ec.resolvers.Query().Search(ctx, args["input"].(model.SearchArgs)) }) if err != nil { ec.Error(ctx, err) @@ -427,7 +394,7 @@ func (ec *executionContext) _User_primitiveResolver(ctx context.Context, field g }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.User_primitiveResolver(ctx, obj) + return ec.resolvers.User().PrimitiveResolver(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -457,7 +424,7 @@ func (ec *executionContext) _User_customResolver(ctx context.Context, field grap }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.User_customResolver(ctx, obj) + return ec.resolvers.User().CustomResolver(ctx, obj) }) if err != nil { ec.Error(ctx, err) diff --git a/example/scalars/resolvers.go b/example/scalars/resolvers.go index 8b45f80246c..3f001bdcd32 100644 --- a/example/scalars/resolvers.go +++ b/example/scalars/resolvers.go @@ -14,7 +14,17 @@ import ( type Resolver struct { } -func (r *Resolver) Query_user(ctx context.Context, id external.ObjectID) (*model.User, error) { +func (r *Resolver) Query() QueryResolver { + return &queryResolver{r} +} + +func (r *Resolver) User() UserResolver { + return &userResolver{r} +} + +type queryResolver struct{ *Resolver } + +func (r *queryResolver) User(ctx context.Context, id external.ObjectID) (*model.User, error) { return &model.User{ ID: id, Name: fmt.Sprintf("Test User %d", id), @@ -24,7 +34,7 @@ func (r *Resolver) Query_user(ctx context.Context, id external.ObjectID) (*model }, nil } -func (r *Resolver) Query_search(ctx context.Context, input model.SearchArgs) ([]model.User, error) { +func (r *queryResolver) Search(ctx context.Context, input model.SearchArgs) ([]model.User, error) { location := model.Point{1, 2} if input.Location != nil { location = *input.Location @@ -53,10 +63,12 @@ func (r *Resolver) Query_search(ctx context.Context, input model.SearchArgs) ([] }, nil } -func (r *Resolver) User_primitiveResolver(ctx context.Context, obj *model.User) (string, error) { +type userResolver struct{ *Resolver } + +func (r *userResolver) PrimitiveResolver(ctx context.Context, obj *model.User) (string, error) { return "test", nil } -func (r *Resolver) User_customResolver(ctx context.Context, obj *model.User) (model.Point, error) { +func (r *userResolver) CustomResolver(ctx context.Context, obj *model.User) (model.Point, error) { return model.Point{5, 1}, nil } diff --git a/example/scalars/scalar_test.go b/example/scalars/scalar_test.go index 96a3eee409c..7e07e096858 100644 --- a/example/scalars/scalar_test.go +++ b/example/scalars/scalar_test.go @@ -22,7 +22,7 @@ type RawUser struct { } func TestScalars(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(&Resolver{}))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(&Resolver{}))) c := client.New(srv.URL) t.Run("marshaling", func(t *testing.T) { diff --git a/example/scalars/server/server.go b/example/scalars/server/server.go index 22805f22244..748213b97ec 100644 --- a/example/scalars/server/server.go +++ b/example/scalars/server/server.go @@ -10,7 +10,7 @@ import ( func main() { http.Handle("/", handler.Playground("Starwars", "/query")) - http.Handle("/query", handler.GraphQL(scalars.MakeExecutableSchema(&scalars.Resolver{}))) + http.Handle("/query", handler.GraphQL(scalars.NewExecutableSchema(&scalars.Resolver{}))) log.Fatal(http.ListenAndServe(":8084", nil)) } diff --git a/example/selection/generated.go b/example/selection/generated.go index e46fbd0c97b..c001c2d6694 100644 --- a/example/selection/generated.go +++ b/example/selection/generated.go @@ -14,18 +14,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Query_events(ctx context.Context) ([]Event, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -35,16 +26,8 @@ type QueryResolver interface { Events(ctx context.Context) ([]Event, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Query_events(ctx context.Context) ([]Event, error) { - return s.r.Query().Events(ctx) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -78,7 +61,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var likeImplementors = []string{"Like", "Event"} @@ -310,7 +293,7 @@ func (ec *executionContext) _Query_events(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_events(ctx) + return ec.resolvers.Query().Events(ctx) }) if err != nil { ec.Error(ctx, err) diff --git a/example/selection/selection.go b/example/selection/selection.go index 7d11be04572..be4486f6b6b 100644 --- a/example/selection/selection.go +++ b/example/selection/selection.go @@ -11,9 +11,15 @@ import ( "github.com/vektah/gqlparser/ast" ) -type SelectionResolver struct{} +type Resolver struct{} -func (r *SelectionResolver) Query_events(ctx context.Context) ([]Event, error) { +func (r *Resolver) Query() QueryResolver { + return &queryResolver{r} +} + +type queryResolver struct{ *Resolver } + +func (r *queryResolver) Events(ctx context.Context) ([]Event, error) { var sels []string reqCtx := graphql.GetRequestContext(ctx) diff --git a/example/selection/selection_test.go b/example/selection/selection_test.go index 4c1829a3aaa..dc3a199549e 100644 --- a/example/selection/selection_test.go +++ b/example/selection/selection_test.go @@ -11,7 +11,7 @@ import ( ) func TestSelection(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(&SelectionResolver{}))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(&Resolver{}))) c := client.New(srv.URL) query := `{ diff --git a/example/selection/server/server.go b/example/selection/server/server.go index e8982e8bd1d..84e291cb5db 100644 --- a/example/selection/server/server.go +++ b/example/selection/server/server.go @@ -10,6 +10,6 @@ import ( func main() { http.Handle("/", handler.Playground("Selection Demo", "/query")) - http.Handle("/query", handler.GraphQL(selection.MakeExecutableSchema(&selection.SelectionResolver{}))) + http.Handle("/query", handler.GraphQL(selection.NewExecutableSchema(&selection.Resolver{}))) log.Fatal(http.ListenAndServe(":8086", nil)) } diff --git a/example/starwars/generated.go b/example/starwars/generated.go index fc0036b3a82..d83d60303c0 100644 --- a/example/starwars/generated.go +++ b/example/starwars/generated.go @@ -15,38 +15,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Droid_friends(ctx context.Context, obj *Droid) ([]Character, error) - Droid_friendsConnection(ctx context.Context, obj *Droid, first *int, after *string) (FriendsConnection, error) - - FriendsConnection_edges(ctx context.Context, obj *FriendsConnection) ([]FriendsEdge, error) - FriendsConnection_friends(ctx context.Context, obj *FriendsConnection) ([]Character, error) - - Human_friends(ctx context.Context, obj *Human) ([]Character, error) - Human_friendsConnection(ctx context.Context, obj *Human, first *int, after *string) (FriendsConnection, error) - - Human_starships(ctx context.Context, obj *Human) ([]Starship, error) - Mutation_createReview(ctx context.Context, episode Episode, review Review) (*Review, error) - - Query_hero(ctx context.Context, episode Episode) (Character, error) - Query_reviews(ctx context.Context, episode Episode, since *time.Time) ([]Review, error) - Query_search(ctx context.Context, text string) ([]SearchResult, error) - Query_character(ctx context.Context, id string) (Character, error) - Query_droid(ctx context.Context, id string) (*Droid, error) - Query_human(ctx context.Context, id string) (*Human, error) - Query_starship(ctx context.Context, id string) (*Starship, error) - - Starship_length(ctx context.Context, obj *Starship, unit LengthUnit) (float64, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -87,76 +58,8 @@ type StarshipResolver interface { Length(ctx context.Context, obj *Starship, unit LengthUnit) (float64, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Droid_friends(ctx context.Context, obj *Droid) ([]Character, error) { - return s.r.Droid().Friends(ctx, obj) -} - -func (s shortMapper) Droid_friendsConnection(ctx context.Context, obj *Droid, first *int, after *string) (FriendsConnection, error) { - return s.r.Droid().FriendsConnection(ctx, obj, first, after) -} - -func (s shortMapper) FriendsConnection_edges(ctx context.Context, obj *FriendsConnection) ([]FriendsEdge, error) { - return s.r.FriendsConnection().Edges(ctx, obj) -} - -func (s shortMapper) FriendsConnection_friends(ctx context.Context, obj *FriendsConnection) ([]Character, error) { - return s.r.FriendsConnection().Friends(ctx, obj) -} - -func (s shortMapper) Human_friends(ctx context.Context, obj *Human) ([]Character, error) { - return s.r.Human().Friends(ctx, obj) -} - -func (s shortMapper) Human_friendsConnection(ctx context.Context, obj *Human, first *int, after *string) (FriendsConnection, error) { - return s.r.Human().FriendsConnection(ctx, obj, first, after) -} - -func (s shortMapper) Human_starships(ctx context.Context, obj *Human) ([]Starship, error) { - return s.r.Human().Starships(ctx, obj) -} - -func (s shortMapper) Mutation_createReview(ctx context.Context, episode Episode, review Review) (*Review, error) { - return s.r.Mutation().CreateReview(ctx, episode, review) -} - -func (s shortMapper) Query_hero(ctx context.Context, episode Episode) (Character, error) { - return s.r.Query().Hero(ctx, episode) -} - -func (s shortMapper) Query_reviews(ctx context.Context, episode Episode, since *time.Time) ([]Review, error) { - return s.r.Query().Reviews(ctx, episode, since) -} - -func (s shortMapper) Query_search(ctx context.Context, text string) ([]SearchResult, error) { - return s.r.Query().Search(ctx, text) -} - -func (s shortMapper) Query_character(ctx context.Context, id string) (Character, error) { - return s.r.Query().Character(ctx, id) -} - -func (s shortMapper) Query_droid(ctx context.Context, id string) (*Droid, error) { - return s.r.Query().Droid(ctx, id) -} - -func (s shortMapper) Query_human(ctx context.Context, id string) (*Human, error) { - return s.r.Query().Human(ctx, id) -} - -func (s shortMapper) Query_starship(ctx context.Context, id string) (*Starship, error) { - return s.r.Query().Starship(ctx, id) -} - -func (s shortMapper) Starship_length(ctx context.Context, obj *Starship, unit LengthUnit) (float64, error) { - return s.r.Starship().Length(ctx, obj, unit) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -202,7 +105,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var droidImplementors = []string{"Droid", "Character"} @@ -276,7 +179,7 @@ func (ec *executionContext) _Droid_friends(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Droid_friends(ctx, obj) + return ec.resolvers.Droid().Friends(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -346,7 +249,7 @@ func (ec *executionContext) _Droid_friendsConnection(ctx context.Context, field }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Droid_friendsConnection(ctx, obj, args["first"].(*int), args["after"].(*string)) + return ec.resolvers.Droid().FriendsConnection(ctx, obj, args["first"].(*int), args["after"].(*string)) }) if err != nil { ec.Error(ctx, err) @@ -447,7 +350,7 @@ func (ec *executionContext) _FriendsConnection_edges(ctx context.Context, field }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.FriendsConnection_edges(ctx, obj) + return ec.resolvers.FriendsConnection().Edges(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -486,7 +389,7 @@ func (ec *executionContext) _FriendsConnection_friends(ctx context.Context, fiel }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.FriendsConnection_friends(ctx, obj) + return ec.resolvers.FriendsConnection().Friends(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -684,7 +587,7 @@ func (ec *executionContext) _Human_friends(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Human_friends(ctx, obj) + return ec.resolvers.Human().Friends(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -754,7 +657,7 @@ func (ec *executionContext) _Human_friendsConnection(ctx context.Context, field }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Human_friendsConnection(ctx, obj, args["first"].(*int), args["after"].(*string)) + return ec.resolvers.Human().FriendsConnection(ctx, obj, args["first"].(*int), args["after"].(*string)) }) if err != nil { ec.Error(ctx, err) @@ -804,7 +707,7 @@ func (ec *executionContext) _Human_starships(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Human_starships(ctx, obj) + return ec.resolvers.Human().Starships(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -883,7 +786,7 @@ func (ec *executionContext) _Mutation_createReview(ctx context.Context, field gr rctx.PushField(field.Alias) defer rctx.Pop() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Mutation_createReview(ctx, args["episode"].(Episode), args["review"].(Review)) + return ec.resolvers.Mutation().CreateReview(ctx, args["episode"].(Episode), args["review"].(Review)) }) if err != nil { ec.Error(ctx, err) @@ -1038,7 +941,7 @@ func (ec *executionContext) _Query_hero(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_hero(ctx, args["episode"].(Episode)) + return ec.resolvers.Query().Hero(ctx, args["episode"].(Episode)) }) if err != nil { ec.Error(ctx, err) @@ -1094,7 +997,7 @@ func (ec *executionContext) _Query_reviews(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_reviews(ctx, args["episode"].(Episode), args["since"].(*time.Time)) + return ec.resolvers.Query().Reviews(ctx, args["episode"].(Episode), args["since"].(*time.Time)) }) if err != nil { ec.Error(ctx, err) @@ -1144,7 +1047,7 @@ func (ec *executionContext) _Query_search(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_search(ctx, args["text"].(string)) + return ec.resolvers.Query().Search(ctx, args["text"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1194,7 +1097,7 @@ func (ec *executionContext) _Query_character(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_character(ctx, args["id"].(string)) + return ec.resolvers.Query().Character(ctx, args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1235,7 +1138,7 @@ func (ec *executionContext) _Query_droid(ctx context.Context, field graphql.Coll }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_droid(ctx, args["id"].(string)) + return ec.resolvers.Query().Droid(ctx, args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1279,7 +1182,7 @@ func (ec *executionContext) _Query_human(ctx context.Context, field graphql.Coll }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_human(ctx, args["id"].(string)) + return ec.resolvers.Query().Human(ctx, args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1323,7 +1226,7 @@ func (ec *executionContext) _Query_starship(ctx context.Context, field graphql.C }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_starship(ctx, args["id"].(string)) + return ec.resolvers.Query().Starship(ctx, args["id"].(string)) }) if err != nil { ec.Error(ctx, err) @@ -1529,7 +1432,7 @@ func (ec *executionContext) _Starship_length(ctx context.Context, field graphql. }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Starship_length(ctx, obj, args["unit"].(LengthUnit)) + return ec.resolvers.Starship().Length(ctx, obj, args["unit"].(LengthUnit)) }) if err != nil { ec.Error(ctx, err) diff --git a/example/starwars/resolvers.go b/example/starwars/resolvers.go index 7113401d923..8cf78469aa1 100644 --- a/example/starwars/resolvers.go +++ b/example/starwars/resolvers.go @@ -16,84 +16,117 @@ type Resolver struct { reviews map[Episode][]Review } -func (r *Resolver) resolveCharacters(ctx context.Context, ids []string) ([]Character, error) { - var result []Character - for _, id := range ids { - char, err := r.Query_character(ctx, id) - if err != nil { - return nil, err - } - result = append(result, char) - } - return result, nil +func (r *Resolver) Droid() DroidResolver { + return &droidResolver{r} } -func (r *Resolver) Human_friends(ctx context.Context, it *Human) ([]Character, error) { - return r.resolveCharacters(ctx, it.FriendIds) +func (r *Resolver) FriendsConnection() FriendsConnectionResolver { + return &friendsConnectionResolver{r} } -func (r *Resolver) Human_friendsConnection(ctx context.Context, it *Human, first *int, after *string) (FriendsConnection, error) { - return r.resolveFriendConnection(ctx, it.FriendIds, first, after) +func (r *Resolver) Human() HumanResolver { + return &humanResolver{r} } -func (r *Resolver) Human_starships(ctx context.Context, it *Human) ([]Starship, error) { - var result []Starship - for _, id := range it.StarshipIds { - char, err := r.Query_starship(ctx, id) +func (r *Resolver) Mutation() MutationResolver { + return &mutationResolver{r} +} + +func (r *Resolver) Query() QueryResolver { + return &queryResolver{r} +} + +func (r *Resolver) Starship() StarshipResolver { + return &starshipResolver{r} +} + +func (r *Resolver) resolveCharacters(ctx context.Context, ids []string) ([]Character, error) { + var result []Character + for _, id := range ids { + char, err := r.Query().Character(ctx, id) if err != nil { return nil, err } - if char != nil { - result = append(result, *char) - } + result = append(result, char) } return result, nil } -func (r *Resolver) Droid_friends(ctx context.Context, it *Droid) ([]Character, error) { - return r.resolveCharacters(ctx, it.FriendIds) +type droidResolver struct{ *Resolver } + +func (r *droidResolver) Friends(ctx context.Context, obj *Droid) ([]Character, error) { + return r.resolveCharacters(ctx, obj.FriendIds) } -func (r *Resolver) Droid_friendsConnection(ctx context.Context, it *Droid, first *int, after *string) (FriendsConnection, error) { - return r.resolveFriendConnection(ctx, it.FriendIds, first, after) +func (r *droidResolver) FriendsConnection(ctx context.Context, obj *Droid, first *int, after *string) (FriendsConnection, error) { + return r.resolveFriendConnection(ctx, obj.FriendIds, first, after) } -func (r *Resolver) FriendsConnection_edges(ctx context.Context, it *FriendsConnection) ([]FriendsEdge, error) { - friends, err := r.resolveCharacters(ctx, it.ids) +type friendsConnectionResolver struct{ *Resolver } + +func (r *friendsConnectionResolver) Edges(ctx context.Context, obj *FriendsConnection) ([]FriendsEdge, error) { + friends, err := r.resolveCharacters(ctx, obj.ids) if err != nil { return nil, err } - edges := make([]FriendsEdge, it.to-it.from) + edges := make([]FriendsEdge, obj.to-obj.from) for i := range edges { edges[i] = FriendsEdge{ - Cursor: encodeCursor(it.from + i), + Cursor: encodeCursor(obj.from + i), Node: friends[i], } } return edges, nil } -// A list of the friends, as a convenience when edges are not needed. -func (r *Resolver) FriendsConnection_friends(ctx context.Context, it *FriendsConnection) ([]Character, error) { - return r.resolveCharacters(ctx, it.ids) +func (r *friendsConnectionResolver) Friends(ctx context.Context, obj *FriendsConnection) ([]Character, error) { + return r.resolveCharacters(ctx, obj.ids) +} + +type humanResolver struct{ *Resolver } + +func (r *humanResolver) Friends(ctx context.Context, obj *Human) ([]Character, error) { + return r.resolveCharacters(ctx, obj.FriendIds) +} + +func (r *humanResolver) FriendsConnection(ctx context.Context, obj *Human, first *int, after *string) (FriendsConnection, error) { + return r.resolveFriendConnection(ctx, obj.FriendIds, first, after) } -func (r *Resolver) Mutation_createReview(ctx context.Context, episode Episode, review Review) (*Review, error) { +func (r *humanResolver) Starships(ctx context.Context, obj *Human) ([]Starship, error) { + var result []Starship + for _, id := range obj.StarshipIds { + char, err := r.Query().Starship(ctx, id) + if err != nil { + return nil, err + } + if char != nil { + result = append(result, *char) + } + } + return result, nil +} + +type mutationResolver struct{ *Resolver } + +func (r *mutationResolver) CreateReview(ctx context.Context, episode Episode, review Review) (*Review, error) { review.Time = time.Now() time.Sleep(1 * time.Second) r.reviews[episode] = append(r.reviews[episode], review) return &review, nil } -func (r *Resolver) Query_hero(ctx context.Context, episode Episode) (Character, error) { +type queryResolver struct{ *Resolver } + +func (r *queryResolver) Hero(ctx context.Context, episode Episode) (Character, error) { if episode == EpisodeEmpire { return r.humans["1000"], nil } return r.droid["2001"], nil } -func (r *Resolver) Query_reviews(ctx context.Context, episode Episode, since *time.Time) ([]Review, error) { +func (r *queryResolver) Reviews(ctx context.Context, episode Episode, since *time.Time) ([]Review, error) { if since == nil { return r.reviews[episode], nil } @@ -107,7 +140,7 @@ func (r *Resolver) Query_reviews(ctx context.Context, episode Episode, since *ti return filtered, nil } -func (r *Resolver) Query_search(ctx context.Context, text string) ([]SearchResult, error) { +func (r *queryResolver) Search(ctx context.Context, text string) ([]SearchResult, error) { var l []SearchResult for _, h := range r.humans { if strings.Contains(h.Name, text) { @@ -127,7 +160,7 @@ func (r *Resolver) Query_search(ctx context.Context, text string) ([]SearchResul return l, nil } -func (r *Resolver) Query_character(ctx context.Context, id string) (Character, error) { +func (r *queryResolver) Character(ctx context.Context, id string) (Character, error) { if h, ok := r.humans[id]; ok { return &h, nil } @@ -136,26 +169,31 @@ func (r *Resolver) Query_character(ctx context.Context, id string) (Character, e } return nil, nil } -func (r *Resolver) Query_droid(ctx context.Context, id string) (*Droid, error) { + +func (r *queryResolver) Droid(ctx context.Context, id string) (*Droid, error) { if d, ok := r.droid[id]; ok { return &d, nil } return nil, nil } -func (r *Resolver) Query_human(ctx context.Context, id string) (*Human, error) { + +func (r *queryResolver) Human(ctx context.Context, id string) (*Human, error) { if h, ok := r.humans[id]; ok { return &h, nil } return nil, nil } -func (r *Resolver) Query_starship(ctx context.Context, id string) (*Starship, error) { + +func (r *queryResolver) Starship(ctx context.Context, id string) (*Starship, error) { if s, ok := r.starships[id]; ok { return &s, nil } return nil, nil } -func (r *Resolver) Starship_length(ctx context.Context, obj *Starship, unit LengthUnit) (float64, error) { +type starshipResolver struct{ *Resolver } + +func (r *starshipResolver) Length(ctx context.Context, obj *Starship, unit LengthUnit) (float64, error) { switch unit { case LengthUnitMeter, "": return obj.Length, nil diff --git a/example/starwars/server/server.go b/example/starwars/server/server.go index 86bdbdc5468..b27404f0490 100644 --- a/example/starwars/server/server.go +++ b/example/starwars/server/server.go @@ -13,7 +13,7 @@ import ( func main() { http.Handle("/", handler.Playground("Starwars", "/query")) - http.Handle("/query", handler.GraphQL(starwars.MakeExecutableSchema(starwars.NewResolver()), + http.Handle("/query", handler.GraphQL(starwars.NewExecutableSchema(starwars.NewResolver()), handler.ResolverMiddleware(func(ctx context.Context, next graphql.Resolver) (res interface{}, err error) { rc := graphql.GetResolverContext(ctx) fmt.Println("Entered", rc.Object, rc.Field.Name) diff --git a/example/starwars/starwars_test.go b/example/starwars/starwars_test.go index 8fbb54547bf..fc35f0b416f 100644 --- a/example/starwars/starwars_test.go +++ b/example/starwars/starwars_test.go @@ -11,7 +11,7 @@ import ( ) func TestStarwars(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(NewResolver()))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(NewResolver()))) c := client.New(srv.URL) t.Run("Lukes starships", func(t *testing.T) { diff --git a/example/todo/generated.go b/example/todo/generated.go index 142f9f79545..135cff5dace 100644 --- a/example/todo/generated.go +++ b/example/todo/generated.go @@ -13,22 +13,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - MyMutation_createTodo(ctx context.Context, todo TodoInput) (Todo, error) - MyMutation_updateTodo(ctx context.Context, id int, changes map[string]interface{}) (*Todo, error) - MyQuery_todo(ctx context.Context, id int) (*Todo, error) - MyQuery_lastTodo(ctx context.Context) (*Todo, error) - MyQuery_todos(ctx context.Context) ([]Todo, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -45,32 +32,8 @@ type MyQueryResolver interface { Todos(ctx context.Context) ([]Todo, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) MyMutation_createTodo(ctx context.Context, todo TodoInput) (Todo, error) { - return s.r.MyMutation().CreateTodo(ctx, todo) -} - -func (s shortMapper) MyMutation_updateTodo(ctx context.Context, id int, changes map[string]interface{}) (*Todo, error) { - return s.r.MyMutation().UpdateTodo(ctx, id, changes) -} - -func (s shortMapper) MyQuery_todo(ctx context.Context, id int) (*Todo, error) { - return s.r.MyQuery().Todo(ctx, id) -} - -func (s shortMapper) MyQuery_lastTodo(ctx context.Context) (*Todo, error) { - return s.r.MyQuery().LastTodo(ctx) -} - -func (s shortMapper) MyQuery_todos(ctx context.Context) ([]Todo, error) { - return s.r.MyQuery().Todos(ctx) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -116,7 +79,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var myMutationImplementors = []string{"MyMutation"} @@ -167,7 +130,7 @@ func (ec *executionContext) _MyMutation_createTodo(ctx context.Context, field gr rctx.PushField(field.Alias) defer rctx.Pop() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.MyMutation_createTodo(ctx, args["todo"].(TodoInput)) + return ec.resolvers.MyMutation().CreateTodo(ctx, args["todo"].(TodoInput)) }) if err != nil { ec.Error(ctx, err) @@ -209,7 +172,7 @@ func (ec *executionContext) _MyMutation_updateTodo(ctx context.Context, field gr rctx.PushField(field.Alias) defer rctx.Pop() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.MyMutation_updateTodo(ctx, args["id"].(int), args["changes"].(map[string]interface{})) + return ec.resolvers.MyMutation().UpdateTodo(ctx, args["id"].(int), args["changes"].(map[string]interface{})) }) if err != nil { ec.Error(ctx, err) @@ -287,7 +250,7 @@ func (ec *executionContext) _MyQuery_todo(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.MyQuery_todo(ctx, args["id"].(int)) + return ec.resolvers.MyQuery().Todo(ctx, args["id"].(int)) }) if err != nil { ec.Error(ctx, err) @@ -320,7 +283,7 @@ func (ec *executionContext) _MyQuery_lastTodo(ctx context.Context, field graphql }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.MyQuery_lastTodo(ctx) + return ec.resolvers.MyQuery().LastTodo(ctx) }) if err != nil { ec.Error(ctx, err) @@ -353,7 +316,7 @@ func (ec *executionContext) _MyQuery_todos(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.MyQuery_todos(ctx) + return ec.resolvers.MyQuery().Todos(ctx) }) if err != nil { ec.Error(ctx, err) diff --git a/test/generated.go b/test/generated.go index 240b8961e06..59019126358 100644 --- a/test/generated.go +++ b/test/generated.go @@ -15,26 +15,9 @@ import ( ast "github.com/vektah/gqlparser/ast" ) -// MakeExecutableSchema creates an ExecutableSchema from the Resolvers interface. -func MakeExecutableSchema(resolvers Resolvers) graphql.ExecutableSchema { - return &executableSchema{resolvers: resolvers} -} - // NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface. func NewExecutableSchema(resolvers ResolverRoot) graphql.ExecutableSchema { - return MakeExecutableSchema(shortMapper{r: resolvers}) -} - -type Resolvers interface { - Element_child(ctx context.Context, obj *models.Element) (models.Element, error) - Element_error(ctx context.Context, obj *models.Element) (bool, error) - Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) - Query_path(ctx context.Context) ([]*models.Element, error) - Query_date(ctx context.Context, filter models.DateFilter) (bool, error) - Query_viewer(ctx context.Context) (*models.Viewer, error) - Query_jsonEncoding(ctx context.Context) (string, error) - - User_likes(ctx context.Context, obj *remote_api.User) ([]string, error) + return &executableSchema{resolvers: resolvers} } type ResolverRoot interface { @@ -57,44 +40,8 @@ type UserResolver interface { Likes(ctx context.Context, obj *remote_api.User) ([]string, error) } -type shortMapper struct { - r ResolverRoot -} - -func (s shortMapper) Element_child(ctx context.Context, obj *models.Element) (models.Element, error) { - return s.r.Element().Child(ctx, obj) -} - -func (s shortMapper) Element_error(ctx context.Context, obj *models.Element) (bool, error) { - return s.r.Element().Error(ctx, obj) -} - -func (s shortMapper) Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) { - return s.r.Element().Mismatched(ctx, obj) -} - -func (s shortMapper) Query_path(ctx context.Context) ([]*models.Element, error) { - return s.r.Query().Path(ctx) -} - -func (s shortMapper) Query_date(ctx context.Context, filter models.DateFilter) (bool, error) { - return s.r.Query().Date(ctx, filter) -} - -func (s shortMapper) Query_viewer(ctx context.Context) (*models.Viewer, error) { - return s.r.Query().Viewer(ctx) -} - -func (s shortMapper) Query_jsonEncoding(ctx context.Context) (string, error) { - return s.r.Query().JsonEncoding(ctx) -} - -func (s shortMapper) User_likes(ctx context.Context, obj *remote_api.User) ([]string, error) { - return s.r.User().Likes(ctx, obj) -} - type executableSchema struct { - resolvers Resolvers + resolvers ResolverRoot } func (e *executableSchema) Schema() *ast.Schema { @@ -128,7 +75,7 @@ func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDe type executionContext struct { *graphql.RequestContext - resolvers Resolvers + resolvers ResolverRoot } var elementImplementors = []string{"Element"} @@ -174,7 +121,7 @@ func (ec *executionContext) _Element_child(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Element_child(ctx, obj) + return ec.resolvers.Element().Child(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -204,7 +151,7 @@ func (ec *executionContext) _Element_error(ctx context.Context, field graphql.Co }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Element_error(ctx, obj) + return ec.resolvers.Element().Error(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -234,7 +181,7 @@ func (ec *executionContext) _Element_mismatched(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Element_mismatched(ctx, obj) + return ec.resolvers.Element().Mismatched(ctx, obj) }) if err != nil { ec.Error(ctx, err) @@ -310,7 +257,7 @@ func (ec *executionContext) _Query_path(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_path(ctx) + return ec.resolvers.Query().Path(ctx) }) if err != nil { ec.Error(ctx, err) @@ -363,7 +310,7 @@ func (ec *executionContext) _Query_date(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_date(ctx, args["filter"].(models.DateFilter)) + return ec.resolvers.Query().Date(ctx, args["filter"].(models.DateFilter)) }) if err != nil { ec.Error(ctx, err) @@ -393,7 +340,7 @@ func (ec *executionContext) _Query_viewer(ctx context.Context, field graphql.Col }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_viewer(ctx) + return ec.resolvers.Query().Viewer(ctx) }) if err != nil { ec.Error(ctx, err) @@ -426,7 +373,7 @@ func (ec *executionContext) _Query_jsonEncoding(ctx context.Context, field graph }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.Query_jsonEncoding(ctx) + return ec.resolvers.Query().JsonEncoding(ctx) }) if err != nil { ec.Error(ctx, err) @@ -531,7 +478,7 @@ func (ec *executionContext) _User_likes(ctx context.Context, field graphql.Colle }() resTmp, err := ec.ResolverMiddleware(ctx, func(ctx context.Context) (interface{}, error) { - return ec.resolvers.User_likes(ctx, obj) + return ec.resolvers.User().Likes(ctx, obj) }) if err != nil { ec.Error(ctx, err) diff --git a/test/resolvers_test.go b/test/resolvers_test.go index 9cada0eb004..c8ab3acfeb7 100644 --- a/test/resolvers_test.go +++ b/test/resolvers_test.go @@ -21,8 +21,8 @@ import ( ) func TestCustomErrorPresenter(t *testing.T) { - resolvers := &testResolvers{} - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(resolvers), + resolvers := &testResolver{} + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(resolvers), handler.ErrorPresenter(func(i context.Context, e error) *gqlerror.Error { if _, ok := errors.Cause(e).(*specialErr); ok { return &gqlerror.Error{Message: "override special error message"} @@ -62,7 +62,7 @@ func TestCustomErrorPresenter(t *testing.T) { } func TestErrorPath(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(&testResolvers{err: fmt.Errorf("boom")}))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(&testResolver{err: fmt.Errorf("boom")}))) c := client.New(srv.URL) var resp struct{} @@ -73,7 +73,7 @@ func TestErrorPath(t *testing.T) { func TestInputDefaults(t *testing.T) { called := false - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(&testResolvers{ + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(&testResolver{ queryDate: func(ctx context.Context, filter models.DateFilter) (bool, error) { assert.Equal(t, "asdf", filter.Value) assert.Equal(t, "UTC", *filter.Timezone) @@ -96,7 +96,7 @@ func TestInputDefaults(t *testing.T) { } func TestJsonEncoding(t *testing.T) { - srv := httptest.NewServer(handler.GraphQL(MakeExecutableSchema(&testResolvers{}))) + srv := httptest.NewServer(handler.GraphQL(NewExecutableSchema(&testResolver{}))) c := client.New(srv.URL) var resp struct { @@ -108,45 +108,63 @@ func TestJsonEncoding(t *testing.T) { require.Equal(t, "\U000fe4ed", resp.JsonEncoding) } -type testResolvers struct { +type testResolver struct { err error queryDate func(ctx context.Context, filter models.DateFilter) (bool, error) } -func (r *testResolvers) Query_jsonEncoding(ctx context.Context) (string, error) { - return "\U000fe4ed", nil +func (r *testResolver) Element() ElementResolver { + return &elementResolver{r} } -func (r *testResolvers) Query_viewer(ctx context.Context) (*models.Viewer, error) { - return &models.Viewer{ - User: &remote_api.User{Name: "Bob"}, - }, nil +func (r *testResolver) Query() QueryResolver { + return &queryResolver{r} } -func (r *testResolvers) Query_date(ctx context.Context, filter models.DateFilter) (bool, error) { - return r.queryDate(ctx, filter) +func (r *testResolver) User() UserResolver { + return &userResolver{r} } -func (r *testResolvers) Query_path(ctx context.Context) ([]*models.Element, error) { - return []*models.Element{{1}, {2}, {3}, {4}}, nil -} +type elementResolver struct{ *testResolver } -func (r *testResolvers) Element_child(ctx context.Context, obj *models.Element) (models.Element, error) { +func (r *elementResolver) Child(ctx context.Context, obj *models.Element) (models.Element, error) { return models.Element{obj.ID * 10}, nil } -func (r *testResolvers) Element_error(ctx context.Context, obj *models.Element) (bool, error) { +func (r *elementResolver) Error(ctx context.Context, obj *models.Element) (bool, error) { // A silly hack to make the result order stable time.Sleep(time.Duration(obj.ID) * 10 * time.Millisecond) return false, r.err } -func (r *testResolvers) Element_mismatched(ctx context.Context, obj *models.Element) ([]bool, error) { +func (r *elementResolver) Mismatched(ctx context.Context, obj *models.Element) ([]bool, error) { return []bool{true}, nil } -func (r *testResolvers) User_likes(ctx context.Context, obj *remote_api.User) ([]string, error) { +type queryResolver struct{ *testResolver } + +func (r *queryResolver) Path(ctx context.Context) ([]*models.Element, error) { + return []*models.Element{{1}, {2}, {3}, {4}}, nil +} + +func (r *queryResolver) Date(ctx context.Context, filter models.DateFilter) (bool, error) { + return r.queryDate(ctx, filter) +} + +func (r *queryResolver) Viewer(ctx context.Context) (*models.Viewer, error) { + return &models.Viewer{ + User: &remote_api.User{Name: "Bob"}, + }, nil +} + +func (r *queryResolver) JsonEncoding(ctx context.Context) (string, error) { + return "\U000fe4ed", nil +} + +type userResolver struct{ *testResolver } + +func (r *userResolver) Likes(ctx context.Context, obj *remote_api.User) ([]string, error) { return obj.Likes, nil }