-
Notifications
You must be signed in to change notification settings - Fork 843
/
Copy pathgraphql.go
127 lines (105 loc) · 3.08 KB
/
graphql.go
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
package graphql
import (
"context"
"github.com/graphql-go/graphql/gqlerrors"
"github.com/graphql-go/graphql/language/parser"
"github.com/graphql-go/graphql/language/source"
)
type Params struct {
// The GraphQL type system to use when validating and executing a query.
Schema Schema
// A GraphQL language formatted string representing the requested operation.
RequestString string
// The value provided as the first argument to resolver functions on the top
// level type (e.g. the query object type).
//
// Deprecated: use the Root field instead.
RootObject map[string]interface{}
// The value provided as the first argument to resolver functions on the top
// level type (e.g. the query object type).
Root interface{}
// A mapping of variable name to runtime value to use for all variables
// defined in the requestString.
VariableValues map[string]interface{}
// The name of the operation to use if requestString contains multiple
// possible operations. Can be omitted if requestString contains only
// one operation.
OperationName string
// Context may be provided to pass application-specific per-request
// information to resolve functions.
Context context.Context
}
func Do(p Params) *Result {
source := source.NewSource(&source.Source{
Body: []byte(p.RequestString),
Name: "GraphQL request",
})
// run init on the extensions
extErrs := handleExtensionsInits(&p)
if len(extErrs) != 0 {
return &Result{
Errors: extErrs,
}
}
extErrs, parseFinishFn := handleExtensionsParseDidStart(&p)
if len(extErrs) != 0 {
return &Result{
Errors: extErrs,
}
}
// parse the source
AST, err := parser.Parse(parser.ParseParams{Source: source})
if err != nil {
// run parseFinishFuncs for extensions
extErrs = parseFinishFn(err)
// merge the errors from extensions and the original error from parser
extErrs = append(extErrs, gqlerrors.FormatErrors(err)...)
return &Result{
Errors: extErrs,
}
}
// run parseFinish functions for extensions
extErrs = parseFinishFn(err)
if len(extErrs) != 0 {
return &Result{
Errors: extErrs,
}
}
// notify extensions about the start of the validation
extErrs, validationFinishFn := handleExtensionsValidationDidStart(&p)
if len(extErrs) != 0 {
return &Result{
Errors: extErrs,
}
}
// validate document
validationResult := ValidateDocument(&p.Schema, AST, nil)
if !validationResult.IsValid {
// run validation finish functions for extensions
extErrs = validationFinishFn(validationResult.Errors)
// merge the errors from extensions and the original error from parser
extErrs = append(extErrs, validationResult.Errors...)
return &Result{
Errors: extErrs,
}
}
// run the validationFinishFuncs for extensions
extErrs = validationFinishFn(validationResult.Errors)
if len(extErrs) != 0 {
return &Result{
Errors: extErrs,
}
}
root := p.Root
if root == nil {
root = p.RootObject
}
return Execute(ExecuteParams{
Schema: p.Schema,
Root: root,
AST: AST,
OperationName: p.OperationName,
Args: p.VariableValues,
Context: p.Context,
})
}