Skip to content

Commit 0c26eae

Browse files
separate query, mutation, subscription resolver
for the purpose of modular resolver if include subscription resolver
1 parent 664d46a commit 0c26eae

File tree

8 files changed

+67
-18
lines changed

8 files changed

+67
-18
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/internal/validation/testdata/graphql-js
22
/internal/validation/testdata/node_modules
33
/vendor
4+
subscription/

go.mod

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
module github.com/agungdwiprasetyo/graphql-go
22

3-
require github.com/opentracing/opentracing-go v1.1.0
3+
require (
4+
github.com/opentracing/opentracing-go v1.1.0
5+
github.com/stretchr/testify v1.4.0 // indirect
6+
)
47

58
go 1.13

go.sum

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,13 @@
1+
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
2+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
24
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
5+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
6+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
7+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
8+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
9+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
10+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
11+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
12+
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
13+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

graphql.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func (s *Schema) Validate(queryString string) []*errors.QueryError {
158158
// without a resolver. If the context get cancelled, no further resolvers will be called and a
159159
// the context error will be returned as soon as possible (not immediately).
160160
func (s *Schema) Exec(ctx context.Context, queryString string, operationName string, variables map[string]interface{}) *Response {
161-
if s.res.Resolver == (reflect.Value{}) {
161+
if s.res.ResolverQuery == (reflect.Value{}) {
162162
panic("schema created without resolver, can not exec")
163163
}
164164
return s.exec(ctx, queryString, operationName, variables, s.res)

internal/exec/exec.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,16 @@ func (r *Request) Execute(ctx context.Context, s *resolvable.Schema, op *query.O
4545
func() {
4646
defer r.handlePanic(ctx)
4747
sels := selected.ApplyOperation(&r.Request, s, op)
48-
r.execSelections(ctx, sels, nil, s, s.Resolver, &out, op.Type == query.Mutation)
48+
var resolver reflect.Value
49+
switch op.Type {
50+
case query.Query:
51+
resolver = s.ResolverQuery
52+
case query.Mutation:
53+
resolver = s.ResolverMutation
54+
case query.Subscription:
55+
resolver = s.ResolverSubscription
56+
}
57+
r.execSelections(ctx, sels, nil, s, resolver, &out, op.Type == query.Mutation)
4958
}()
5059

5160
if err := ctx.Err(); err != nil {

internal/exec/resolvable/resolvable.go

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,23 @@ import (
1111
"github.com/agungdwiprasetyo/graphql-go/internal/schema"
1212
)
1313

14+
type QueryResolver interface {
15+
Query() interface{}
16+
}
17+
18+
type MutationResolver interface {
19+
Mutation() interface{}
20+
}
21+
22+
type SubscriptionResolver interface {
23+
Subscription() interface{}
24+
}
25+
1426
type Schema struct {
1527
*Meta
1628
schema.Schema
17-
Query Resolvable
18-
Mutation Resolvable
19-
Subscription Resolvable
20-
Resolver reflect.Value
29+
Query, Mutation, Subscription Resolvable
30+
ResolverQuery, ResolverMutation, ResolverSubscription reflect.Value
2131
}
2232

2333
type Resolvable interface {
@@ -70,20 +80,33 @@ func ApplyResolver(s *schema.Schema, resolver interface{}) (*Schema, error) {
7080

7181
var query, mutation, subscription Resolvable
7282

83+
queryResolver := resolver
84+
if r, ok := resolver.(QueryResolver); ok {
85+
queryResolver = r.Query()
86+
}
87+
mutationResolver := resolver
88+
if r, ok := resolver.(MutationResolver); ok {
89+
mutationResolver = r.Mutation()
90+
}
91+
subscriptionResolver := resolver
92+
if r, ok := resolver.(SubscriptionResolver); ok {
93+
subscriptionResolver = r.Subscription()
94+
}
95+
7396
if t, ok := s.EntryPoints["query"]; ok {
74-
if err := b.assignExec(&query, t, reflect.TypeOf(resolver)); err != nil {
97+
if err := b.assignExec(&query, t, reflect.TypeOf(queryResolver)); err != nil {
7598
return nil, err
7699
}
77100
}
78101

79102
if t, ok := s.EntryPoints["mutation"]; ok {
80-
if err := b.assignExec(&mutation, t, reflect.TypeOf(resolver)); err != nil {
103+
if err := b.assignExec(&mutation, t, reflect.TypeOf(mutationResolver)); err != nil {
81104
return nil, err
82105
}
83106
}
84107

85108
if t, ok := s.EntryPoints["subscription"]; ok {
86-
if err := b.assignExec(&subscription, t, reflect.TypeOf(resolver)); err != nil {
109+
if err := b.assignExec(&subscription, t, reflect.TypeOf(subscriptionResolver)); err != nil {
87110
return nil, err
88111
}
89112
}
@@ -93,12 +116,14 @@ func ApplyResolver(s *schema.Schema, resolver interface{}) (*Schema, error) {
93116
}
94117

95118
return &Schema{
96-
Meta: newMeta(s),
97-
Schema: *s,
98-
Resolver: reflect.ValueOf(resolver),
99-
Query: query,
100-
Mutation: mutation,
101-
Subscription: subscription,
119+
Meta: newMeta(s),
120+
Schema: *s,
121+
ResolverQuery: reflect.ValueOf(queryResolver),
122+
ResolverMutation: reflect.ValueOf(mutationResolver),
123+
ResolverSubscription: reflect.ValueOf(subscriptionResolver),
124+
Query: query,
125+
Mutation: mutation,
126+
Subscription: subscription,
102127
}, nil
103128
}
104129

internal/exec/subscribe.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *query
2929

3030
sels := selected.ApplyOperation(&r.Request, s, op)
3131
var fields []*fieldToExec
32-
collectFieldsToResolve(sels, s, s.Resolver, &fields, make(map[string]*fieldToExec))
32+
collectFieldsToResolve(sels, s, s.ResolverSubscription, &fields, make(map[string]*fieldToExec))
3333

3434
// TODO: move this check into validation.Validate
3535
if len(fields) != 1 {

subscriptions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import (
2121
// further resolvers will be called. The context error will be returned as soon
2222
// as possible (not immediately).
2323
func (s *Schema) Subscribe(ctx context.Context, queryString string, operationName string, variables map[string]interface{}) (<-chan interface{}, error) {
24-
if s.res.Resolver == (reflect.Value{}) {
24+
if s.res.ResolverSubscription == (reflect.Value{}) {
2525
return nil, errors.New("schema created without resolver, can not subscribe")
2626
}
2727
if _, ok := s.schema.EntryPoints["subscription"]; !ok {

0 commit comments

Comments
 (0)