diff --git a/codebase/app/graphql_server/graphql_handler.go b/codebase/app/graphql_server/graphql_handler.go
new file mode 100644
index 00000000..018f58de
--- /dev/null
+++ b/codebase/app/graphql_server/graphql_handler.go
@@ -0,0 +1,305 @@
+package graphqlserver
+
+import (
+ "context"
+ "encoding/json"
+ "fmt"
+ "io"
+ "net"
+ "net/http"
+ "os"
+ "reflect"
+ "runtime"
+ "strconv"
+
+ "github.com/golangid/candi/candihelper"
+ "github.com/golangid/candi/candishared"
+ "github.com/golangid/candi/codebase/app/graphql_server/ws"
+ "github.com/golangid/candi/codebase/factory"
+ "github.com/golangid/candi/logger"
+ "github.com/golangid/candi/tracer"
+ "github.com/golangid/graphql-go"
+ gqltypes "github.com/golangid/graphql-go/types"
+)
+
+// Handler interface
+type Handler interface {
+ ServeGraphQL() http.HandlerFunc
+ ServePlayground(resp http.ResponseWriter, req *http.Request)
+ ServeVoyager(resp http.ResponseWriter, req *http.Request)
+}
+
+// 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()
+
+ appendStructField(rootName, query, &queryResolverFields)
+ appendStructField(rootName, mutation, &mutationResolverFields)
+ appendStructField(rootName, subscription, &subscriptionResolverFields)
+
+ queryResolverValues[rootName] = query
+ mutationResolverValues[rootName] = mutation
+ subscriptionResolverValues[rootName] = subscription
+ }
+ }
+
+ 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,
+ "permissionACL": service.GetDependency().GetMiddleware().GraphQLPermissionACL,
+ }
+ for directive, dirFunc := range opt.directiveFuncs {
+ directiveFuncs[directive] = dirFunc
+ }
+
+ schemaOpts := []graphql.SchemaOpt{
+ graphql.UseStringDescriptions(),
+ graphql.UseFieldResolvers(),
+ graphql.Tracer(&graphqlTracer{}),
+ graphql.Logger(&panicLogger{}),
+ graphql.DirectiveFuncs(directiveFuncs),
+ }
+ if opt.DisableIntrospection {
+ // handling vulnerabilities exploit schema
+ schemaOpts = append(schemaOpts, graphql.DisableIntrospection())
+ }
+ schema := graphql.MustParseSchema(string(gqlSchema), &opt.rootResolver, schemaOpts...)
+
+ logger.LogYellow(fmt.Sprintf("[GraphQL] endpoint\t\t\t: http://127.0.0.1:%d%s%s", opt.httpPort, opt.rootPath, rootGraphQLPath))
+ logger.LogYellow(fmt.Sprintf("[GraphQL] playground\t\t\t: http://127.0.0.1:%d%s%s", opt.httpPort, opt.rootPath, rootGraphQLPlayground))
+ logger.LogYellow(fmt.Sprintf("[GraphQL] playground (with explorer)\t: http://127.0.0.1:%d%s%s?graphiql=true", opt.httpPort, opt.rootPath, rootGraphQLPlayground))
+ logger.LogYellow(fmt.Sprintf("[GraphQL] voyager\t\t\t: http://127.0.0.1:%d%s%s", opt.httpPort, opt.rootPath, rootGraphQLVoyager))
+
+ return &handlerImpl{
+ disableIntrospection: opt.DisableIntrospection,
+ schema: schema,
+ }
+}
+
+type handlerImpl struct {
+ disableIntrospection bool
+ schema *graphql.Schema
+}
+
+func NewHandler(disableIntrospection bool, schema *graphql.Schema) Handler {
+ return &handlerImpl{
+ disableIntrospection: disableIntrospection,
+ schema: schema,
+ }
+}
+
+func (s *handlerImpl) ServeGraphQL() http.HandlerFunc {
+
+ return ws.NewHandlerFunc(s.schema, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
+
+ var params struct {
+ Query string `json:"query"`
+ OperationName string `json:"operationName"`
+ Variables map[string]interface{} `json:"variables"`
+ }
+ body, err := io.ReadAll(req.Body)
+ if err != nil {
+ http.Error(resp, err.Error(), http.StatusBadRequest)
+ return
+ }
+ if err := json.Unmarshal(body, ¶ms); err != nil {
+ params.Query = string(body)
+ }
+
+ req.Header.Set(candihelper.HeaderXRealIP, extractRealIPHeader(req))
+
+ ctx := context.WithValue(req.Context(), candishared.ContextKeyHTTPHeader, req.Header)
+ response := s.schema.Exec(ctx, params.Query, params.OperationName, params.Variables)
+ responseJSON, err := json.Marshal(response)
+ if err != nil {
+ http.Error(resp, err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ resp.Header().Set(candihelper.HeaderContentType, candihelper.HeaderMIMEApplicationJSON)
+ resp.Write(responseJSON)
+ }))
+}
+
+func (s *handlerImpl) ServePlayground(resp http.ResponseWriter, req *http.Request) {
+ if s.disableIntrospection {
+ http.Error(resp, "Forbidden", http.StatusForbidden)
+ return
+ }
+
+ if ok, _ := strconv.ParseBool(req.URL.Query().Get("graphiql")); ok {
+ resp.Write([]byte(`
+
+
+
+ Candi GraphiQL
+
+
+
+
+
+
+
+
+`))
+ return
+ }
+
+ resp.Write([]byte(`
+
+
+
+
+
+
+
+
+ Playground
+
+
+
+
+
+
+`))
+}
+
+func (s *handlerImpl) ServeVoyager(resp http.ResponseWriter, req *http.Request) {
+ if s.disableIntrospection {
+ http.Error(resp, "Forbidden", http.StatusForbidden)
+ return
+ }
+ resp.Write([]byte(`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Loading...
+
+
+`))
+}
+
+// panicLogger is the default logger used to log panics that occur during query execution
+type panicLogger struct{}
+
+// LogPanic is used to log recovered panic values that occur during query execution
+// https://github.com/graph-gophers/graphql-go/blob/master/log/log.go#L19 + custom add log to trace
+func (l *panicLogger) LogPanic(ctx context.Context, value interface{}) {
+ const size = 2 << 10
+ buf := make([]byte, size)
+ buf = buf[:runtime.Stack(buf, false)]
+
+ tracer.Log(ctx, "gql_panic", value)
+ tracer.Log(ctx, "gql_panic_trace", buf)
+}
+
+func extractRealIPHeader(req *http.Request) string {
+ for _, header := range []string{candihelper.HeaderXForwardedFor, candihelper.HeaderXRealIP} {
+ if ip := req.Header.Get(header); ip != "" {
+ return ip
+ }
+ }
+
+ ip, _, _ := net.SplitHostPort(req.RemoteAddr)
+ return ip
+}
diff --git a/codebase/app/graphql_server/graphql_server.go b/codebase/app/graphql_server/graphql_server.go
index 66799c90..1d8a5ae8 100644
--- a/codebase/app/graphql_server/graphql_server.go
+++ b/codebase/app/graphql_server/graphql_server.go
@@ -2,37 +2,18 @@ package graphqlserver
import (
"context"
- "encoding/json"
"fmt"
- "io"
"log"
"net"
"net/http"
- "os"
- "reflect"
- "runtime"
-
- "github.com/golangid/candi/candihelper"
- "github.com/golangid/candi/candishared"
- "github.com/golangid/candi/codebase/app/graphql_server/static"
- "github.com/golangid/candi/codebase/app/graphql_server/ws"
+
"github.com/golangid/candi/codebase/factory"
"github.com/golangid/candi/codebase/factory/types"
- "github.com/golangid/candi/logger"
- "github.com/golangid/candi/tracer"
"github.com/golangid/candi/wrapper"
- graphql "github.com/golangid/graphql-go"
- gqltypes "github.com/golangid/graphql-go/types"
"github.com/soheilhy/cmux"
)
-const (
- rootGraphQLPath = "/graphql"
- rootGraphQLPlayground = "/graphql/playground"
- rootGraphQLVoyager = "/graphql/voyager"
-)
-
type graphqlServer struct {
opt Option
httpEngine *http.Server
@@ -51,7 +32,7 @@ func NewServer(service factory.ServiceFactory, opts ...OptionFunc) factory.AppSe
opt(&server.opt)
}
- httpHandler := NewHandler(service, server.opt)
+ httpHandler := ConstructHandlerFromService(service, server.opt)
mux := http.NewServeMux()
mux.Handle("/", server.opt.rootHandler)
@@ -60,12 +41,9 @@ func NewServer(service factory.ServiceFactory, opts ...OptionFunc) factory.AppSe
mux.HandleFunc(server.opt.rootPath+rootGraphQLPlayground, httpHandler.ServePlayground)
mux.HandleFunc(server.opt.rootPath+rootGraphQLVoyager, httpHandler.ServeVoyager)
- httpEngine.Addr = server.opt.httpPort
+ httpEngine.Addr = fmt.Sprintf(":%d", server.opt.httpPort)
httpEngine.Handler = mux
- logger.LogYellow("[GraphQL] endpoint : " + server.opt.rootPath + rootGraphQLPath)
- logger.LogYellow("[GraphQL] playground : " + server.opt.rootPath + rootGraphQLPlayground)
- logger.LogYellow("[GraphQL] voyager : " + server.opt.rootPath + rootGraphQLVoyager)
fmt.Printf("\x1b[34;1m⇨ GraphQL HTTP server run at port [::]%s\x1b[0m\n\n", httpEngine.Addr)
if server.opt.sharedListener != nil {
@@ -83,9 +61,8 @@ func (s *graphqlServer) Serve() {
err = s.httpEngine.ListenAndServe()
}
- switch e := err.(type) {
- case *net.OpError:
- panic(fmt.Errorf("gql http server: %v", e))
+ if err != nil {
+ log.Panicf("GraphQL Server: Unexpected Error: %v", err)
}
}
@@ -101,141 +78,3 @@ func (s *graphqlServer) Shutdown(ctx context.Context) {
func (s *graphqlServer) Name() string {
return string(types.GraphQL)
}
-
-// Handler interface
-type Handler interface {
- ServeGraphQL() http.HandlerFunc
- ServePlayground(resp http.ResponseWriter, req *http.Request)
- ServeVoyager(resp http.ResponseWriter, req *http.Request)
-}
-
-// NewHandler for create public graphql handler (maybe inject to rest handler)
-func NewHandler(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()
-
- appendStructField(rootName, query, &queryResolverFields)
- appendStructField(rootName, mutation, &mutationResolverFields)
- appendStructField(rootName, subscription, &subscriptionResolverFields)
-
- queryResolverValues[rootName] = query
- mutationResolverValues[rootName] = mutation
- subscriptionResolverValues[rootName] = subscription
- }
- }
-
- 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,
- "permissionACL": service.GetDependency().GetMiddleware().GraphQLPermissionACL,
- }
- for directive, dirFunc := range opt.directiveFuncs {
- directiveFuncs[directive] = dirFunc
- }
-
- schemaOpts := []graphql.SchemaOpt{
- graphql.UseStringDescriptions(),
- graphql.UseFieldResolvers(),
- graphql.Tracer(&graphqlTracer{}),
- graphql.Logger(&panicLogger{}),
- graphql.DirectiveFuncs(directiveFuncs),
- }
- if opt.DisableIntrospection {
- // handling vulnerabilities exploit schema
- schemaOpts = append(schemaOpts, graphql.DisableIntrospection())
- }
- schema := graphql.MustParseSchema(string(gqlSchema), &opt.rootResolver, schemaOpts...)
-
- return &handlerImpl{
- disableIntrospection: opt.DisableIntrospection,
- schema: schema,
- }
-}
-
-type handlerImpl struct {
- disableIntrospection bool
- schema *graphql.Schema
-}
-
-func (s *handlerImpl) ServeGraphQL() http.HandlerFunc {
-
- return ws.NewHandlerFunc(s.schema, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
-
- var params struct {
- Query string `json:"query"`
- OperationName string `json:"operationName"`
- Variables map[string]interface{} `json:"variables"`
- }
- body, err := io.ReadAll(req.Body)
- if err != nil {
- http.Error(resp, err.Error(), http.StatusBadRequest)
- return
- }
- if err := json.Unmarshal(body, ¶ms); err != nil {
- params.Query = string(body)
- }
-
- ip := req.Header.Get(candihelper.HeaderXForwardedFor)
- if ip == "" {
- ip = req.Header.Get(candihelper.HeaderXRealIP)
- if ip == "" {
- ip, _, _ = net.SplitHostPort(req.RemoteAddr)
- }
- }
- req.Header.Set(candihelper.HeaderXRealIP, ip)
-
- ctx := context.WithValue(req.Context(), candishared.ContextKeyHTTPHeader, req.Header)
- response := s.schema.Exec(ctx, params.Query, params.OperationName, params.Variables)
- responseJSON, err := json.Marshal(response)
- if err != nil {
- http.Error(resp, err.Error(), http.StatusInternalServerError)
- return
- }
-
- resp.Header().Set(candihelper.HeaderContentType, candihelper.HeaderMIMEApplicationJSON)
- resp.Write(responseJSON)
- }))
-}
-
-func (s *handlerImpl) ServePlayground(resp http.ResponseWriter, req *http.Request) {
- if s.disableIntrospection {
- http.Error(resp, "Forbidden", http.StatusForbidden)
- return
- }
- resp.Write([]byte(static.PlaygroundAsset))
-}
-
-func (s *handlerImpl) ServeVoyager(resp http.ResponseWriter, req *http.Request) {
- if s.disableIntrospection {
- http.Error(resp, "Forbidden", http.StatusForbidden)
- return
- }
- resp.Write([]byte(static.VoyagerAsset))
-}
-
-// panicLogger is the default logger used to log panics that occur during query execution
-type panicLogger struct{}
-
-// LogPanic is used to log recovered panic values that occur during query execution
-// https://github.com/graph-gophers/graphql-go/blob/master/log/log.go#L19 + custom add log to trace
-func (l *panicLogger) LogPanic(ctx context.Context, value interface{}) {
- const size = 64 << 10
- buf := make([]byte, size)
- buf = buf[:runtime.Stack(buf, false)]
-
- tracer.Log(ctx, "gql_panic", value)
- tracer.Log(ctx, "gql_panic_trace", buf)
-}
diff --git a/codebase/app/graphql_server/option.go b/codebase/app/graphql_server/option.go
index de02b052..c8519831 100644
--- a/codebase/app/graphql_server/option.go
+++ b/codebase/app/graphql_server/option.go
@@ -1,7 +1,6 @@
package graphqlserver
import (
- "fmt"
"net/http"
"github.com/golangid/candi/wrapper"
@@ -9,12 +8,18 @@ import (
"github.com/soheilhy/cmux"
)
+const (
+ rootGraphQLPath = "/graphql"
+ rootGraphQLPlayground = "/graphql/playground"
+ rootGraphQLVoyager = "/graphql/voyager"
+)
+
type (
// Option gql server
Option struct {
DisableIntrospection bool
- httpPort string
+ httpPort uint16
rootPath string
debugMode bool
jaegerMaxPacketSize int
@@ -30,7 +35,7 @@ type (
func getDefaultOption() Option {
return Option{
- httpPort: ":8000",
+ httpPort: 8000,
rootPath: "",
debugMode: true,
rootHandler: http.HandlerFunc(wrapper.HTTPHandlerDefaultRoot),
@@ -40,7 +45,7 @@ func getDefaultOption() Option {
// SetHTTPPort option func
func SetHTTPPort(port uint16) OptionFunc {
return func(o *Option) {
- o.httpPort = fmt.Sprintf(":%d", port)
+ o.httpPort = port
}
}
@@ -110,11 +115,11 @@ func SetRootSubscription(resolver interface{}) OptionFunc {
}
// AddDirectiveFunc option func
-func AddDirectiveFunc(directiveName string, dirFuncs types.DirectiveFunc) OptionFunc {
+func AddDirectiveFunc(directiveName string, handlerFunc types.DirectiveFunc) OptionFunc {
return func(o *Option) {
if o.directiveFuncs == nil {
o.directiveFuncs = make(map[string]types.DirectiveFunc)
}
- o.directiveFuncs[directiveName] = dirFuncs
+ o.directiveFuncs[directiveName] = handlerFunc
}
}
diff --git a/codebase/app/graphql_server/static/static_template.go b/codebase/app/graphql_server/static/static_template.go
deleted file mode 100644
index 09bc750f..00000000
--- a/codebase/app/graphql_server/static/static_template.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package static
-
-const (
- // PlaygroundAsset template
- PlaygroundAsset = `
-
-
-
-
-
-
-
-
-
- Playground
-
-
-
-
-
-
- `
-
- // VoyagerAsset template
- VoyagerAsset = `
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Loading...
-
-
-`
-)
diff --git a/codebase/app/grpc_server/grpc_server.go b/codebase/app/grpc_server/grpc_server.go
index 4af9a974..f51bfb7b 100644
--- a/codebase/app/grpc_server/grpc_server.go
+++ b/codebase/app/grpc_server/grpc_server.go
@@ -98,7 +98,7 @@ func NewServer(service factory.ServiceFactory, opts ...OptionFunc) factory.AppSe
func (s *grpcServer) Serve() {
if err := s.serverEngine.Serve(s.listener); err != nil {
- log.Println("GRPC: Unexpected Error", err)
+ log.Panicf("GRPC: Unexpected Error: %v", err)
}
}
diff --git a/codebase/app/rest_server/option.go b/codebase/app/rest_server/option.go
index 511010d5..5da01d9f 100644
--- a/codebase/app/rest_server/option.go
+++ b/codebase/app/rest_server/option.go
@@ -1,7 +1,6 @@
package restserver
import (
- "fmt"
"net/http"
"os"
@@ -14,18 +13,17 @@ import (
type (
option struct {
- rootMiddlewares []echo.MiddlewareFunc
- rootHandler http.Handler
- errorHandler echo.HTTPErrorHandler
- httpPort string
- rootPath string
- debugMode bool
- includeGraphQL bool
- graphqlDisableIntrospection bool
- jaegerMaxPacketSize int
- sharedListener cmux.CMux
- engineOption func(e *echo.Echo)
- graphqlOption graphqlserver.Option
+ rootMiddlewares []echo.MiddlewareFunc
+ rootHandler http.Handler
+ errorHandler echo.HTTPErrorHandler
+ httpPort uint16
+ rootPath string
+ debugMode bool
+ includeGraphQL bool
+ jaegerMaxPacketSize int
+ sharedListener cmux.CMux
+ engineOption func(e *echo.Echo)
+ graphqlOption graphqlserver.Option
}
// OptionFunc type
@@ -34,7 +32,7 @@ type (
func getDefaultOption() option {
return option{
- httpPort: ":8000",
+ httpPort: 8000,
rootPath: "",
debugMode: true,
rootMiddlewares: []echo.MiddlewareFunc{
@@ -56,7 +54,7 @@ func getDefaultOption() option {
// SetHTTPPort option func
func SetHTTPPort(port uint16) OptionFunc {
return func(o *option) {
- o.httpPort = fmt.Sprintf(":%d", port)
+ o.httpPort = port
}
}
@@ -95,13 +93,6 @@ func SetIncludeGraphQL(includeGraphQL bool) OptionFunc {
}
}
-// SetGraphQLDisableIntrospection option func
-func SetGraphQLDisableIntrospection(graphqlDisableIntrospection bool) OptionFunc {
- return func(o *option) {
- o.graphqlDisableIntrospection = graphqlDisableIntrospection
- }
-}
-
// SetJaegerMaxPacketSize option func
func SetJaegerMaxPacketSize(max int) OptionFunc {
return func(o *option) {
diff --git a/codebase/app/rest_server/rest_server.go b/codebase/app/rest_server/rest_server.go
index 424c4447..0a505357 100644
--- a/codebase/app/rest_server/rest_server.go
+++ b/codebase/app/rest_server/rest_server.go
@@ -74,17 +74,13 @@ func NewServer(service factory.ServiceFactory, opts ...OptionFunc) factory.AppSe
// inject graphql handler to rest server
if server.opt.includeGraphQL {
- graphqlHandler := graphqlserver.NewHandler(service, server.opt.graphqlOption)
+ graphqlHandler := graphqlserver.ConstructHandlerFromService(service, server.opt.graphqlOption)
server.serverEngine.Any(server.opt.rootPath+"/graphql", echo.WrapHandler(graphqlHandler.ServeGraphQL()))
server.serverEngine.GET(server.opt.rootPath+"/graphql/playground", echo.WrapHandler(http.HandlerFunc(graphqlHandler.ServePlayground)))
server.serverEngine.GET(server.opt.rootPath+"/graphql/voyager", echo.WrapHandler(http.HandlerFunc(graphqlHandler.ServeVoyager)))
-
- logger.LogYellow("[GraphQL] endpoint : " + server.opt.rootPath + "/graphql")
- logger.LogYellow("[GraphQL] playground : " + server.opt.rootPath + "/graphql/playground")
- logger.LogYellow("[GraphQL] voyager : " + server.opt.rootPath + "/graphql/voyager")
}
- fmt.Printf("\x1b[34;1m⇨ HTTP server run at port [::]%s\x1b[0m\n\n", server.opt.httpPort)
+ fmt.Printf("\x1b[34;1m⇨ HTTP server run at port [::]:%d\x1b[0m\n\n", server.opt.httpPort)
return server
}
@@ -99,12 +95,11 @@ func (h *restServer) Serve() {
h.serverEngine.Listener = h.listener
err = h.serverEngine.Start("")
} else {
- err = h.serverEngine.Start(h.opt.httpPort)
+ err = h.serverEngine.Start(fmt.Sprintf(":%d", h.opt.httpPort))
}
- switch e := err.(type) {
- case *net.OpError:
- panic(fmt.Errorf("rest server: %v", e))
+ if err != nil {
+ log.Panicf("REST Server: Unexpected Error: %v", err)
}
}
diff --git a/codebase/app/task_queue_worker/graphql_resolver.go b/codebase/app/task_queue_worker/graphql_resolver.go
index 04ef4512..ecaf1002 100644
--- a/codebase/app/task_queue_worker/graphql_resolver.go
+++ b/codebase/app/task_queue_worker/graphql_resolver.go
@@ -4,24 +4,22 @@ import (
"context"
"errors"
"fmt"
+ "log"
"net/http"
"runtime"
"sort"
"strings"
"time"
+ "github.com/golangid/candi"
dashboard "github.com/golangid/candi-plugin/task-queue-worker/dashboard"
"github.com/golangid/candi/candihelper"
+ "github.com/golangid/candi/candishared"
+ graphqlserver "github.com/golangid/candi/codebase/app/graphql_server"
+ "github.com/golangid/candi/config/env"
"github.com/golangid/candi/logger"
"github.com/golangid/graphql-go"
- "github.com/golangid/graphql-go/relay"
"github.com/golangid/graphql-go/trace"
-
- "github.com/golangid/candi"
- "github.com/golangid/candi/candishared"
- "github.com/golangid/candi/codebase/app/graphql_server/static"
- "github.com/golangid/candi/codebase/app/graphql_server/ws"
- "github.com/golangid/candi/config/env"
)
func (t *taskQueueWorker) serveGraphQLAPI() {
@@ -38,16 +36,17 @@ func (t *taskQueueWorker) serveGraphQLAPI() {
mux.Handle("/job", t.opt.basicAuth(http.StripPrefix("/", http.FileServer(dashboard.Dashboard))))
mux.Handle("/expired", t.opt.basicAuth(http.StripPrefix("/", http.FileServer(dashboard.Dashboard))))
- mux.HandleFunc("/graphql", ws.NewHandlerFunc(schema, &relay.Handler{Schema: schema}))
- mux.HandleFunc("/voyager", func(rw http.ResponseWriter, r *http.Request) { rw.Write([]byte(static.VoyagerAsset)) })
- mux.HandleFunc("/playground", func(rw http.ResponseWriter, r *http.Request) { rw.Write([]byte(static.PlaygroundAsset)) })
+ gqlHandler := graphqlserver.NewHandler(false, schema)
+ mux.HandleFunc("/graphql", gqlHandler.ServeGraphQL())
+ mux.HandleFunc("/playground", gqlHandler.ServePlayground)
+ mux.HandleFunc("/voyager", gqlHandler.ServeVoyager)
httpEngine := new(http.Server)
httpEngine.Addr = fmt.Sprintf(":%d", engine.opt.dashboardPort)
httpEngine.Handler = mux
if err := httpEngine.ListenAndServe(); err != nil {
- panic(fmt.Errorf("task queue worker dashboard: %v", err))
+ log.Panicf("task queue worker dashboard: %v", err)
}
}
diff --git a/codebase/factory/appfactory/setup_rest_server.go b/codebase/factory/appfactory/setup_rest_server.go
index bff66dc4..1d49ee0b 100644
--- a/codebase/factory/appfactory/setup_rest_server.go
+++ b/codebase/factory/appfactory/setup_rest_server.go
@@ -1,6 +1,7 @@
package appfactory
import (
+ graphqlserver "github.com/golangid/candi/codebase/app/graphql_server"
restserver "github.com/golangid/candi/codebase/app/rest_server"
"github.com/golangid/candi/codebase/factory"
"github.com/golangid/candi/config/env"
@@ -16,6 +17,12 @@ func SetupRESTServer(service factory.ServiceFactory, opts ...restserver.OptionFu
restserver.SetDebugMode(env.BaseEnv().DebugMode),
restserver.SetJaegerMaxPacketSize(env.BaseEnv().JaegerMaxPacketSize),
}
+ if env.BaseEnv().UseGraphQL {
+ restOptions = append(restOptions, restserver.AddGraphQLOption(
+ graphqlserver.SetDisableIntrospection(env.BaseEnv().GraphQLDisableIntrospection),
+ graphqlserver.SetHTTPPort(env.BaseEnv().HTTPPort),
+ ))
+ }
restOptions = append(restOptions, opts...)
return restserver.NewServer(service, restOptions...)
}
diff --git a/init.go b/init.go
index 7645cd23..f2e421b4 100644
--- a/init.go
+++ b/init.go
@@ -2,5 +2,5 @@ package candi
const (
// Version of this library
- Version = "v1.14.4"
+ Version = "v1.14.5"
)