Skip to content

Commit 04ce3fa

Browse files
change type of directive func & add err extension
1 parent 7f18f91 commit 04ce3fa

File tree

7 files changed

+60
-41
lines changed

7 files changed

+60
-41
lines changed

example/auth_directive/module.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ directive @auth on FIELD_DEFINITION
1818
1919
type Query {
2020
# @candi:queryRoot
21-
user: UserQueryResolver
21+
user: UserQueryResolver @auth
2222
}
2323
2424
type Mutation {
@@ -60,7 +60,7 @@ enum FilterSortEnum {
6060
6161
# UserModule Resolver Area
6262
type UserQueryResolver {
63-
getAllUser(filter: FilterListInputResolver): UserListResolver! @auth
63+
getAllUser(filter: FilterListInputResolver): UserListResolver!
6464
getDetailUser(id: String!): UserResolver!
6565
}
6666

example/auth_directive/server/server.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package main
33
import (
44
"context"
55
"encoding/json"
6-
"errors"
76
"io"
87
"log"
98
"net/http"
@@ -14,27 +13,40 @@ import (
1413
"github.com/golangid/graphql-go/ws"
1514
)
1615

16+
type extensionser struct {
17+
}
18+
19+
func (extensionser) Error() string {
20+
return "Unauthorized"
21+
}
22+
func (extensionser) Extensions() map[string]interface{} {
23+
return map[string]interface{}{
24+
"code": 401,
25+
}
26+
}
27+
1728
type authDirective struct {
1829
}
1930

20-
func (v *authDirective) Exec(ctx context.Context, directive *types.Directive, input interface{}) (context.Context, error) {
31+
func (v *authDirective) Auth(ctx context.Context, directive *types.Directive, input interface{}) (context.Context, error) {
2132

2233
headers, _ := ctx.Value("header").(http.Header)
2334
if headers.Get("Authorization") == "" {
24-
return ctx, errors.New("Unauthorized")
35+
return ctx, &extensionser{}
2536
}
2637

2738
return context.WithValue(ctx, "claim", "wkwkwkwk"), nil
2839
}
2940

3041
func main() {
42+
dir := &authDirective{}
3143
opts := []graphql.SchemaOpt{
3244
graphql.UseStringDescriptions(),
3345
graphql.UseFieldResolvers(),
3446
graphql.MaxParallelism(20),
35-
graphql.DirectiveExecutors(
36-
map[string]types.DirectiveExecutor{
37-
"auth": &authDirective{},
47+
graphql.DirectiveFuncs(
48+
map[string]types.DirectiveFunc{
49+
"auth": dir.Auth,
3850
},
3951
),
4052
}

graphql.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ type Schema struct {
8484
useStringDescriptions bool
8585
disableIntrospection bool
8686
subscribeResolverTimeout time.Duration
87-
executors map[string]types.DirectiveExecutor
87+
directiveFuncs map[string]types.DirectiveFunc
8888
}
8989

9090
func (s *Schema) ASTSchema() *types.Schema {
@@ -171,11 +171,11 @@ func SubscribeResolverTimeout(timeout time.Duration) SchemaOpt {
171171
}
172172
}
173173

174-
// DirectiveExecutors allows to pass custom directive visitors that will be able to handle
174+
// DirectiveFuncs allows to pass custom directive visitors that will be able to handle
175175
// your GraphQL schema directives.
176-
func DirectiveExecutors(executors map[string]types.DirectiveExecutor) SchemaOpt {
176+
func DirectiveFuncs(dirFuncs map[string]types.DirectiveFunc) SchemaOpt {
177177
return func(s *Schema) {
178-
s.executors = executors
178+
s.directiveFuncs = dirFuncs
179179
}
180180
}
181181

@@ -264,11 +264,11 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str
264264
Schema: s.schema,
265265
DisableIntrospection: s.disableIntrospection,
266266
},
267-
Limiter: make(chan struct{}, s.maxParallelism),
268-
Tracer: s.tracer,
269-
Logger: s.logger,
270-
PanicHandler: s.panicHandler,
271-
DirectiveExecutors: s.executors,
267+
Limiter: make(chan struct{}, s.maxParallelism),
268+
Tracer: s.tracer,
269+
Logger: s.logger,
270+
PanicHandler: s.panicHandler,
271+
DirectiveFuncs: s.directiveFuncs,
272272
}
273273
varTypes := make(map[string]*introspection.Type)
274274
for _, v := range op.Vars {

internal/exec/exec.go

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ type Request struct {
2626
Logger log.Logger
2727
PanicHandler errors.PanicHandler
2828
SubscribeResolverTimeout time.Duration
29-
DirectiveExecutors map[string]types.DirectiveExecutor
29+
DirectiveFuncs map[string]types.DirectiveFunc
3030
}
3131

3232
func (r *Request) handlePanic(ctx context.Context) {
@@ -229,21 +229,22 @@ func execFieldSelection(ctx context.Context, r *Request, s *resolvable.Schema, f
229229
}
230230

231231
res := f.resolver
232-
if f.field.UseMethodResolver() {
233-
234-
for _, directive := range f.field.Directives {
235-
if executor, ok := r.DirectiveExecutors[directive.Name.Name]; ok {
236-
var dirErr error
237-
ctx, dirErr = executor.Exec(ctx, directive, f.field.PackedArgs)
238-
if dirErr != nil {
239-
err := errors.Errorf("%s", dirErr)
240-
err.Path = path.toSlice()
241-
err.ResolverError = dirErr
242-
return err
232+
for _, directive := range f.field.Directives {
233+
if dirFunc, ok := r.DirectiveFuncs[directive.Name.Name]; ok {
234+
var dirErr error
235+
ctx, dirErr = dirFunc(ctx, directive, f.field.PackedArgs)
236+
if dirErr != nil {
237+
err := errors.Errorf("%s", dirErr)
238+
err.Path = path.toSlice()
239+
err.ResolverError = dirErr
240+
if ex, ok := dirErr.(extensionser); ok {
241+
err.Extensions = ex.Extensions()
243242
}
243+
return err
244244
}
245245
}
246-
246+
}
247+
if f.field.UseMethodResolver() {
247248
var in []reflect.Value
248249
if f.field.HasContext {
249250
in = append(in, reflect.ValueOf(ctx))

internal/exec/subscribe.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,16 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
3030
}
3131

3232
for _, directive := range f.field.Directives {
33-
if executor, ok := r.DirectiveExecutors[directive.Name.Name]; ok {
33+
if dirFunc, ok := r.DirectiveFuncs[directive.Name.Name]; ok {
3434
var dirErr error
35-
ctx, dirErr = executor.Exec(ctx, directive, f.field.PackedArgs)
35+
ctx, dirErr = dirFunc(ctx, directive, f.field.PackedArgs)
3636
if dirErr != nil {
37-
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{errors.Errorf("%s", dirErr)}})
37+
err := errors.Errorf("%s", dirErr)
38+
err.ResolverError = dirErr
39+
if ex, ok := dirErr.(extensionser); ok {
40+
err.Extensions = ex.Extensions()
41+
}
42+
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}})
3843
}
3944
}
4045
}
@@ -65,6 +70,9 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
6570
resolverErr := callOut[1].Interface().(error)
6671
err = errors.Errorf("%s", resolverErr)
6772
err.ResolverError = resolverErr
73+
if ex, ok := callOut[1].Interface().(extensionser); ok {
74+
err.Extensions = ex.Extensions()
75+
}
6876
}
6977

7078
if err != nil {
@@ -117,10 +125,10 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
117125
Vars: r.Request.Vars,
118126
Schema: r.Request.Schema,
119127
},
120-
Limiter: r.Limiter,
121-
Tracer: r.Tracer,
122-
Logger: r.Logger,
123-
DirectiveExecutors: r.DirectiveExecutors,
128+
Limiter: r.Limiter,
129+
Tracer: r.Tracer,
130+
Logger: r.Logger,
131+
DirectiveFuncs: r.DirectiveFuncs,
124132
}
125133
var out bytes.Buffer
126134
func() {

subscriptions.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func (s *Schema) subscribe(ctx context.Context, queryString string, operationNam
5959
Logger: s.logger,
6060
PanicHandler: s.panicHandler,
6161
SubscribeResolverTimeout: s.subscribeResolverTimeout,
62-
DirectiveExecutors: s.executors,
62+
DirectiveFuncs: s.directiveFuncs,
6363
}
6464
varTypes := make(map[string]*introspection.Type)
6565
for _, v := range op.Vars {

types/directive.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,7 @@ type DirectiveDefinition struct {
2828

2929
type DirectiveList []*Directive
3030

31-
type DirectiveExecutor interface {
32-
Exec(ctx context.Context, directive *Directive, input interface{}) (context.Context, error)
33-
}
31+
type DirectiveFunc func(ctx context.Context, directive *Directive, input interface{}) (context.Context, error)
3432

3533
// Returns the Directive in the DirectiveList by name or nil if not found.
3634
func (l DirectiveList) Get(name string) *Directive {

0 commit comments

Comments
 (0)