-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgraphql.go
More file actions
135 lines (115 loc) · 3.48 KB
/
graphql.go
File metadata and controls
135 lines (115 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// SPDX-License-Identifier: EUPL-1.2
package api
import (
"net/http"
"strings"
"github.com/99designs/gqlgen/graphql"
"github.com/99designs/gqlgen/graphql/handler"
"github.com/99designs/gqlgen/graphql/playground"
"github.com/gin-gonic/gin"
)
// defaultGraphQLPath is the URL path where the GraphQL endpoint is mounted.
const defaultGraphQLPath = "/graphql"
// graphqlConfig holds configuration for the GraphQL endpoint.
type graphqlConfig struct {
schema graphql.ExecutableSchema
path string
playground bool
}
// GraphQLConfig captures the configured GraphQL endpoint settings for an Engine.
//
// It is intentionally small and serialisable so callers can inspect the active
// GraphQL surface without reaching into the internal handler configuration.
//
// Example:
//
// cfg := api.GraphQLConfig{Enabled: true, Path: "/graphql", Playground: true}
type GraphQLConfig struct {
Enabled bool
Path string
Playground bool
PlaygroundPath string
}
// GraphQLConfig returns the currently configured GraphQL settings for the engine.
//
// The result snapshots the Engine state at call time and normalises any configured
// URL path using the same rules as the runtime handlers.
//
// Example:
//
// cfg := engine.GraphQLConfig()
func (e *Engine) GraphQLConfig() GraphQLConfig {
if e == nil {
return GraphQLConfig{}
}
cfg := GraphQLConfig{
Enabled: e.graphql != nil,
Playground: e.graphql != nil && e.graphql.playground,
}
if e.graphql != nil {
cfg.Path = normaliseGraphQLPath(e.graphql.path)
if e.graphql.playground {
cfg.PlaygroundPath = cfg.Path + "/playground"
}
}
return cfg
}
// GraphQLOption configures a GraphQL endpoint.
//
// Example:
//
// opts := []api.GraphQLOption{api.WithPlayground(), api.WithGraphQLPath("/gql")}
type GraphQLOption func(*graphqlConfig)
// WithPlayground enables the GraphQL Playground UI at {path}/playground.
//
// Example:
//
// api.WithGraphQL(schema, api.WithPlayground())
func WithPlayground() GraphQLOption {
return func(cfg *graphqlConfig) {
cfg.playground = true
}
}
// WithGraphQLPath sets a custom URL path for the GraphQL endpoint.
// The default path is "/graphql".
//
// Example:
//
// api.WithGraphQL(schema, api.WithGraphQLPath("/gql"))
func WithGraphQLPath(path string) GraphQLOption {
return func(cfg *graphqlConfig) {
cfg.path = normaliseGraphQLPath(path)
}
}
// mountGraphQL registers the GraphQL handler and optional playground on the Gin engine.
func mountGraphQL(r *gin.Engine, cfg *graphqlConfig) {
srv := handler.NewDefaultServer(cfg.schema)
graphqlHandler := gin.WrapH(srv)
// Mount the GraphQL endpoint for all HTTP methods (POST for queries/mutations,
// GET for playground redirects and introspection).
r.Any(cfg.path, graphqlHandler)
if cfg.playground {
playgroundPath := cfg.path + "/playground"
playgroundHandler := playground.Handler("GraphQL", cfg.path)
r.GET(playgroundPath, wrapHTTPHandler(playgroundHandler))
}
}
// normaliseGraphQLPath coerces custom GraphQL paths into a stable form.
// The path always begins with a single slash and never ends with one.
func normaliseGraphQLPath(path string) string {
path = strings.TrimSpace(path)
if path == "" {
return defaultGraphQLPath
}
path = "/" + strings.Trim(path, "/")
if path == "/" {
return defaultGraphQLPath
}
return path
}
// wrapHTTPHandler adapts a standard http.Handler to a Gin handler function.
func wrapHTTPHandler(h http.Handler) gin.HandlerFunc {
return func(c *gin.Context) {
h.ServeHTTP(c.Writer, c.Request)
}
}