1{{ reserveImport "context" }}
2{{ reserveImport "fmt" }}
3{{ reserveImport "io" }}
4{{ reserveImport "strconv" }}
5{{ reserveImport "time" }}
6{{ reserveImport "sync" }}
7{{ reserveImport "sync/atomic" }}
8{{ reserveImport "errors" }}
9{{ reserveImport "bytes" }}
10
11{{ reserveImport "github.com/vektah/gqlparser" }}
12{{ reserveImport "github.com/vektah/gqlparser/ast" }}
13{{ reserveImport "github.com/99designs/gqlgen/graphql" }}
14{{ reserveImport "github.com/99designs/gqlgen/graphql/introspection" }}
15
16
17// NewExecutableSchema creates an ExecutableSchema from the ResolverRoot interface.
18func NewExecutableSchema(cfg Config) graphql.ExecutableSchema {
19 return &executableSchema{
20 resolvers: cfg.Resolvers,
21 directives: cfg.Directives,
22 complexity: cfg.Complexity,
23 }
24}
25
26type Config struct {
27 Resolvers ResolverRoot
28 Directives DirectiveRoot
29 Complexity ComplexityRoot
30}
31
32type ResolverRoot interface {
33{{- range $object := .Objects -}}
34 {{ if $object.HasResolvers -}}
35 {{$object.Name}}() {{$object.Name}}Resolver
36 {{ end }}
37{{- end }}
38}
39
40type DirectiveRoot struct {
41{{ range $directive := .Directives }}
42 {{ $directive.Declaration }}
43{{ end }}
44}
45
46type ComplexityRoot struct {
47{{ range $object := .Objects }}
48 {{ if not $object.IsReserved -}}
49 {{ $object.Name|go }} struct {
50 {{ range $_, $fields := $object.UniqueFields }}
51 {{- $field := index $fields 0 -}}
52 {{ if not $field.IsReserved -}}
53 {{ $field.GoFieldName }} {{ $field.ComplexitySignature }}
54 {{ end }}
55 {{- end }}
56 }
57 {{- end }}
58{{ end }}
59}
60
61{{ range $object := .Objects -}}
62 {{ if $object.HasResolvers }}
63 type {{$object.Name}}Resolver interface {
64 {{ range $field := $object.Fields -}}
65 {{- if $field.IsResolver }}
66 {{- $field.GoFieldName}}{{ $field.ShortResolverDeclaration }}
67 {{- end }}
68 {{ end }}
69 }
70 {{- end }}
71{{- end }}
72
73type executableSchema struct {
74 resolvers ResolverRoot
75 directives DirectiveRoot
76 complexity ComplexityRoot
77}
78
79func (e *executableSchema) Schema() *ast.Schema {
80 return parsedSchema
81}
82
83func (e *executableSchema) Complexity(typeName, field string, childComplexity int, rawArgs map[string]interface{}) (int, bool) {
84 ec := executionContext{nil, e}
85 _ = ec
86 switch typeName + "." + field {
87 {{ range $object := .Objects }}
88 {{ if not $object.IsReserved }}
89 {{ range $_, $fields := $object.UniqueFields }}
90 {{- $len := len $fields }}
91 {{- range $i, $field := $fields }}
92 {{- $last := eq (add $i 1) $len }}
93 {{- if not $field.IsReserved }}
94 {{- if eq $i 0 }}case {{ end }}"{{$object.Name}}.{{$field.Name}}"{{ if not $last }},{{ else }}:
95 if e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}} == nil {
96 break
97 }
98 {{ if $field.Args }}
99 args, err := ec.{{ $field.ArgsFunc }}(context.TODO(),rawArgs)
100 if err != nil {
101 return 0, false
102 }
103 {{ end }}
104 return e.complexity.{{$object.Name|go}}.{{$field.GoFieldName}}(childComplexity{{if $field.Args}}, {{$field.ComplexityArgs}} {{ end }}), true
105 {{ end }}
106 {{- end }}
107 {{- end }}
108 {{ end }}
109 {{ end }}
110 {{ end }}
111 }
112 return 0, false
113}
114
115func (e *executableSchema) Query(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
116 {{- if .QueryRoot }}
117 ec := executionContext{graphql.GetRequestContext(ctx), e}
118
119 buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
120 data := ec._{{.QueryRoot.Name}}(ctx, op.SelectionSet)
121 var buf bytes.Buffer
122 data.MarshalGQL(&buf)
123 return buf.Bytes()
124 })
125
126 return &graphql.Response{
127 Data: buf,
128 Errors: ec.Errors,
129 Extensions: ec.Extensions,
130 }
131 {{- else }}
132 return graphql.ErrorResponse(ctx, "queries are not supported")
133 {{- end }}
134}
135
136func (e *executableSchema) Mutation(ctx context.Context, op *ast.OperationDefinition) *graphql.Response {
137 {{- if .MutationRoot }}
138 ec := executionContext{graphql.GetRequestContext(ctx), e}
139
140 buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
141 data := ec._{{.MutationRoot.Name}}(ctx, op.SelectionSet)
142 var buf bytes.Buffer
143 data.MarshalGQL(&buf)
144 return buf.Bytes()
145 })
146
147 return &graphql.Response{
148 Data: buf,
149 Errors: ec.Errors,
150 Extensions: ec.Extensions,
151 }
152 {{- else }}
153 return graphql.ErrorResponse(ctx, "mutations are not supported")
154 {{- end }}
155}
156
157func (e *executableSchema) Subscription(ctx context.Context, op *ast.OperationDefinition) func() *graphql.Response {
158 {{- if .SubscriptionRoot }}
159 ec := executionContext{graphql.GetRequestContext(ctx), e}
160
161 next := ec._{{.SubscriptionRoot.Name}}(ctx, op.SelectionSet)
162 if ec.Errors != nil {
163 return graphql.OneShot(&graphql.Response{Data: []byte("null"), Errors: ec.Errors})
164 }
165
166 var buf bytes.Buffer
167 return func() *graphql.Response {
168 buf := ec.RequestMiddleware(ctx, func(ctx context.Context) []byte {
169 buf.Reset()
170 data := next()
171
172 if data == nil {
173 return nil
174 }
175 data.MarshalGQL(&buf)
176 return buf.Bytes()
177 })
178
179 if buf == nil {
180 return nil
181 }
182
183 return &graphql.Response{
184 Data: buf,
185 Errors: ec.Errors,
186 Extensions: ec.Extensions,
187 }
188 }
189 {{- else }}
190 return graphql.OneShot(graphql.ErrorResponse(ctx, "subscriptions are not supported"))
191 {{- end }}
192}
193
194type executionContext struct {
195 *graphql.RequestContext
196 *executableSchema
197}
198
199func (ec *executionContext) FieldMiddleware(ctx context.Context, obj interface{}, next graphql.Resolver) (ret interface{}) {
200 defer func() {
201 if r := recover(); r != nil {
202 ec.Error(ctx, ec.Recover(ctx, r))
203 ret = nil
204 }
205 }()
206 {{- if .Directives }}
207 rctx := graphql.GetResolverContext(ctx)
208 for _, d := range rctx.Field.Definition.Directives {
209 switch d.Name {
210 {{- range $directive := .Directives }}
211 case "{{$directive.Name}}":
212 if ec.directives.{{$directive.Name|ucFirst}} != nil {
213 {{- if $directive.Args }}
214 rawArgs := d.ArgumentMap(ec.Variables)
215 args, err := ec.{{ $directive.ArgsFunc }}(ctx,rawArgs)
216 if err != nil {
217 ec.Error(ctx, err)
218 return nil
219 }
220 {{- end }}
221 n := next
222 next = func(ctx context.Context) (interface{}, error) {
223 return ec.directives.{{$directive.Name|ucFirst}}({{$directive.CallArgs}})
224 }
225 }
226 {{- end }}
227 }
228 }
229 {{- end }}
230 res, err := ec.ResolverMiddleware(ctx, next)
231 if err != nil {
232 ec.Error(ctx, err)
233 return nil
234 }
235 return res
236}
237
238func (ec *executionContext) introspectSchema() (*introspection.Schema, error) {
239 if ec.DisableIntrospection {
240 return nil, errors.New("introspection disabled")
241 }
242 return introspection.WrapSchema(parsedSchema), nil
243}
244
245func (ec *executionContext) introspectType(name string) (*introspection.Type, error) {
246 if ec.DisableIntrospection {
247 return nil, errors.New("introspection disabled")
248 }
249 return introspection.WrapTypeFromDef(parsedSchema, parsedSchema.Types[name]), nil
250}
251
252var parsedSchema = gqlparser.MustLoadSchema(
253 {{- range $filename, $schema := .SchemaStr }}
254 &ast.Source{Name: {{$filename|quote}}, Input: {{$schema|rawQuote}}},
255 {{- end }}
256)