Skip to content

Commit

Permalink
change type of directive func & add err extension
Browse files Browse the repository at this point in the history
  • Loading branch information
agungdwiprasetyo committed Sep 8, 2022
1 parent 7f18f91 commit 04ce3fa
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 41 deletions.
4 changes: 2 additions & 2 deletions example/auth_directive/module.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ directive @auth on FIELD_DEFINITION
type Query {
# @candi:queryRoot
user: UserQueryResolver
user: UserQueryResolver @auth
}
type Mutation {
Expand Down Expand Up @@ -60,7 +60,7 @@ enum FilterSortEnum {
# UserModule Resolver Area
type UserQueryResolver {
getAllUser(filter: FilterListInputResolver): UserListResolver! @auth
getAllUser(filter: FilterListInputResolver): UserListResolver!
getDetailUser(id: String!): UserResolver!
}
Expand Down
24 changes: 18 additions & 6 deletions example/auth_directive/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"context"
"encoding/json"
"errors"
"io"
"log"
"net/http"
Expand All @@ -14,27 +13,40 @@ import (
"github.com/golangid/graphql-go/ws"
)

type extensionser struct {
}

func (extensionser) Error() string {
return "Unauthorized"
}
func (extensionser) Extensions() map[string]interface{} {
return map[string]interface{}{
"code": 401,
}
}

type authDirective struct {
}

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

headers, _ := ctx.Value("header").(http.Header)
if headers.Get("Authorization") == "" {
return ctx, errors.New("Unauthorized")
return ctx, &extensionser{}
}

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

func main() {
dir := &authDirective{}
opts := []graphql.SchemaOpt{
graphql.UseStringDescriptions(),
graphql.UseFieldResolvers(),
graphql.MaxParallelism(20),
graphql.DirectiveExecutors(
map[string]types.DirectiveExecutor{
"auth": &authDirective{},
graphql.DirectiveFuncs(
map[string]types.DirectiveFunc{
"auth": dir.Auth,
},
),
}
Expand Down
18 changes: 9 additions & 9 deletions graphql.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ type Schema struct {
useStringDescriptions bool
disableIntrospection bool
subscribeResolverTimeout time.Duration
executors map[string]types.DirectiveExecutor
directiveFuncs map[string]types.DirectiveFunc
}

func (s *Schema) ASTSchema() *types.Schema {
Expand Down Expand Up @@ -171,11 +171,11 @@ func SubscribeResolverTimeout(timeout time.Duration) SchemaOpt {
}
}

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

Expand Down Expand Up @@ -264,11 +264,11 @@ func (s *Schema) exec(ctx context.Context, queryString string, operationName str
Schema: s.schema,
DisableIntrospection: s.disableIntrospection,
},
Limiter: make(chan struct{}, s.maxParallelism),
Tracer: s.tracer,
Logger: s.logger,
PanicHandler: s.panicHandler,
DirectiveExecutors: s.executors,
Limiter: make(chan struct{}, s.maxParallelism),
Tracer: s.tracer,
Logger: s.logger,
PanicHandler: s.panicHandler,
DirectiveFuncs: s.directiveFuncs,
}
varTypes := make(map[string]*introspection.Type)
for _, v := range op.Vars {
Expand Down
27 changes: 14 additions & 13 deletions internal/exec/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ type Request struct {
Logger log.Logger
PanicHandler errors.PanicHandler
SubscribeResolverTimeout time.Duration
DirectiveExecutors map[string]types.DirectiveExecutor
DirectiveFuncs map[string]types.DirectiveFunc
}

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

res := f.resolver
if f.field.UseMethodResolver() {

for _, directive := range f.field.Directives {
if executor, ok := r.DirectiveExecutors[directive.Name.Name]; ok {
var dirErr error
ctx, dirErr = executor.Exec(ctx, directive, f.field.PackedArgs)
if dirErr != nil {
err := errors.Errorf("%s", dirErr)
err.Path = path.toSlice()
err.ResolverError = dirErr
return err
for _, directive := range f.field.Directives {
if dirFunc, ok := r.DirectiveFuncs[directive.Name.Name]; ok {
var dirErr error
ctx, dirErr = dirFunc(ctx, directive, f.field.PackedArgs)
if dirErr != nil {
err := errors.Errorf("%s", dirErr)
err.Path = path.toSlice()
err.ResolverError = dirErr
if ex, ok := dirErr.(extensionser); ok {
err.Extensions = ex.Extensions()
}
return err
}
}

}
if f.field.UseMethodResolver() {
var in []reflect.Value
if f.field.HasContext {
in = append(in, reflect.ValueOf(ctx))
Expand Down
22 changes: 15 additions & 7 deletions internal/exec/subscribe.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,16 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
}

for _, directive := range f.field.Directives {
if executor, ok := r.DirectiveExecutors[directive.Name.Name]; ok {
if dirFunc, ok := r.DirectiveFuncs[directive.Name.Name]; ok {
var dirErr error
ctx, dirErr = executor.Exec(ctx, directive, f.field.PackedArgs)
ctx, dirErr = dirFunc(ctx, directive, f.field.PackedArgs)
if dirErr != nil {
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{errors.Errorf("%s", dirErr)}})
err := errors.Errorf("%s", dirErr)
err.ResolverError = dirErr
if ex, ok := dirErr.(extensionser); ok {
err.Extensions = ex.Extensions()
}
return sendAndReturnClosed(&Response{Errors: []*errors.QueryError{err}})
}
}
}
Expand Down Expand Up @@ -65,6 +70,9 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
resolverErr := callOut[1].Interface().(error)
err = errors.Errorf("%s", resolverErr)
err.ResolverError = resolverErr
if ex, ok := callOut[1].Interface().(extensionser); ok {
err.Extensions = ex.Extensions()
}
}

if err != nil {
Expand Down Expand Up @@ -117,10 +125,10 @@ func (r *Request) Subscribe(ctx context.Context, s *resolvable.Schema, op *types
Vars: r.Request.Vars,
Schema: r.Request.Schema,
},
Limiter: r.Limiter,
Tracer: r.Tracer,
Logger: r.Logger,
DirectiveExecutors: r.DirectiveExecutors,
Limiter: r.Limiter,
Tracer: r.Tracer,
Logger: r.Logger,
DirectiveFuncs: r.DirectiveFuncs,
}
var out bytes.Buffer
func() {
Expand Down
2 changes: 1 addition & 1 deletion subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func (s *Schema) subscribe(ctx context.Context, queryString string, operationNam
Logger: s.logger,
PanicHandler: s.panicHandler,
SubscribeResolverTimeout: s.subscribeResolverTimeout,
DirectiveExecutors: s.executors,
DirectiveFuncs: s.directiveFuncs,
}
varTypes := make(map[string]*introspection.Type)
for _, v := range op.Vars {
Expand Down
4 changes: 1 addition & 3 deletions types/directive.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ type DirectiveDefinition struct {

type DirectiveList []*Directive

type DirectiveExecutor interface {
Exec(ctx context.Context, directive *Directive, input interface{}) (context.Context, error)
}
type DirectiveFunc func(ctx context.Context, directive *Directive, input interface{}) (context.Context, error)

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

0 comments on commit 04ce3fa

Please sign in to comment.