Skip to content

Commit

Permalink
graphql: enhance set root resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
agungdwiprasetyo committed Sep 14, 2023
1 parent ec09c44 commit 27866ae
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 47 deletions.
50 changes: 29 additions & 21 deletions codebase/app/graphql_server/graphql_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,31 +31,33 @@ type Handler interface {

// ConstructHandlerFromService for create public graphql handler (maybe inject to rest handler)
func ConstructHandlerFromService(service factory.ServiceFactory, opt Option) Handler {
// create dynamic struct
queryResolverValues := make(map[string]interface{})
mutationResolverValues := make(map[string]interface{})
subscriptionResolverValues := make(map[string]interface{})
var queryResolverFields, mutationResolverFields, subscriptionResolverFields []reflect.StructField
for _, m := range service.GetModules() {
if resolverModule := m.GraphQLHandler(); resolverModule != nil {
rootName := string(m.Name())
query, mutation, subscription := resolverModule.Query(), resolverModule.Mutation(), resolverModule.Subscription()
if opt.rootResolver == nil {
// create dynamic struct
queryResolverValues := make(map[string]interface{})
mutationResolverValues := make(map[string]interface{})
subscriptionResolverValues := make(map[string]interface{})
var queryResolverFields, mutationResolverFields, subscriptionResolverFields []reflect.StructField
for _, m := range service.GetModules() {
if resolverModule := m.GraphQLHandler(); resolverModule != nil {
rootName := string(m.Name())
query, mutation, subscription := resolverModule.Query(), resolverModule.Mutation(), resolverModule.Subscription()

appendStructField(rootName, query, &queryResolverFields)
appendStructField(rootName, mutation, &mutationResolverFields)
appendStructField(rootName, subscription, &subscriptionResolverFields)
appendStructField(rootName, query, &queryResolverFields)
appendStructField(rootName, mutation, &mutationResolverFields)
appendStructField(rootName, subscription, &subscriptionResolverFields)

queryResolverValues[rootName] = query
mutationResolverValues[rootName] = mutation
subscriptionResolverValues[rootName] = subscription
queryResolverValues[rootName] = query
mutationResolverValues[rootName] = mutation
subscriptionResolverValues[rootName] = subscription
}
}
opt.rootResolver = &rootResolver{
rootQuery: constructStruct(queryResolverFields, queryResolverValues),
rootMutation: constructStruct(mutationResolverFields, mutationResolverValues),
rootSubscription: constructStruct(subscriptionResolverFields, subscriptionResolverValues),
}
}

opt.rootResolver.rootQuery = constructStruct(queryResolverFields, queryResolverValues)
opt.rootResolver.rootMutation = constructStruct(mutationResolverFields, mutationResolverValues)
opt.rootResolver.rootSubscription = constructStruct(subscriptionResolverFields, subscriptionResolverValues)
gqlSchema := candihelper.LoadAllFile(os.Getenv(candihelper.WORKDIR)+"api/graphql", ".graphql")

// default directive
directiveFuncs := map[string]gqltypes.DirectiveFunc{
"auth": service.GetDependency().GetMiddleware().GraphQLAuth,
Expand All @@ -76,7 +78,13 @@ func ConstructHandlerFromService(service factory.ServiceFactory, opt Option) Han
// handling vulnerabilities exploit schema
schemaOpts = append(schemaOpts, graphql.DisableIntrospection())
}
schema := graphql.MustParseSchema(string(gqlSchema), &opt.rootResolver, schemaOpts...)

gqlSchema := candihelper.LoadAllFile(os.Getenv(candihelper.WORKDIR)+"api/graphql", ".graphql")
schema := graphql.MustParseSchema(string(gqlSchema), &rootResolver{
rootQuery: opt.rootResolver.Query(),
rootMutation: opt.rootResolver.Mutation(),
rootSubscription: opt.rootResolver.Subscription(),
}, schemaOpts...)

logger.LogYellow(fmt.Sprintf("[GraphQL] endpoint\t\t\t: http://127.0.0.1:%d%s", opt.httpPort, opt.RootPath))
logger.LogYellow(fmt.Sprintf("[GraphQL] playground\t\t\t: http://127.0.0.1:%d%s/playground", opt.httpPort, opt.RootPath))
Expand Down
25 changes: 5 additions & 20 deletions codebase/app/graphql_server/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"net/http"
"strings"

"github.com/golangid/candi/codebase/interfaces"
"github.com/golangid/candi/wrapper"
"github.com/golangid/graphql-go/types"
"github.com/soheilhy/cmux"
Expand All @@ -20,7 +21,7 @@ type (
jaegerMaxPacketSize int
rootHandler http.Handler
sharedListener cmux.CMux
rootResolver RootResolver
rootResolver interfaces.GraphQLHandler
directiveFuncs map[string]types.DirectiveFunc
}

Expand Down Expand Up @@ -89,26 +90,10 @@ func SetJaegerMaxPacketSize(max int) OptionFunc {
}
}

// SetRootQuery option func
func SetRootQuery(resolver interface{}) OptionFunc {
// SetRootResolver option func
func SetRootResolver(resolver interfaces.GraphQLHandler) OptionFunc {
return func(o *Option) {
o.rootResolver.rootQuery = resolver
}
}

// SetRootMutation option func
func SetRootMutation(resolver interface{}) OptionFunc {
return func(o *Option) {
o.rootResolver.rootMutation = resolver
}
}

// SetRootSubscription public function
// this public method created because cannot create dynamic method for embedded struct (issue https://github.com/golang/go/issues/15924)
// and subscription in graphql cannot subscribe to at most one subscription at a time
func SetRootSubscription(resolver interface{}) OptionFunc {
return func(o *Option) {
o.rootResolver.rootSubscription = resolver
o.rootResolver = resolver
}
}

Expand Down
10 changes: 5 additions & 5 deletions codebase/app/graphql_server/root_resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,21 @@ package graphqlserver

import "reflect"

// RootResolver root
// rootResolver root
// issue https://github.com/graph-gophers/graphql-go/issues/145
type RootResolver struct {
type rootResolver struct {
rootQuery interface{}
rootMutation interface{}
rootSubscription interface{}
}

func (r *RootResolver) Query() interface{} {
func (r *rootResolver) Query() interface{} {
return r.rootQuery
}
func (r *RootResolver) Mutation() interface{} {
func (r *rootResolver) Mutation() interface{} {
return r.rootMutation
}
func (r *RootResolver) Subscription() interface{} {
func (r *rootResolver) Subscription() interface{} {
return r.rootSubscription
}

Expand Down
2 changes: 1 addition & 1 deletion init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ package candi

const (
// Version of this library
Version = "v1.15.8"
Version = "v1.15.9"
)

0 comments on commit 27866ae

Please sign in to comment.