1package graphql 2 3import ( 4 "context" 5 6 "github.com/graphql-go/graphql/gqlerrors" 7 "github.com/graphql-go/graphql/language/parser" 8 "github.com/graphql-go/graphql/language/source" 9) 10 11type Params struct { 12 // The GraphQL type system to use when validating and executing a query. 13 Schema Schema 14 15 // A GraphQL language formatted string representing the requested operation. 16 RequestString string 17 18 // The value provided as the first argument to resolver functions on the top 19 // level type (e.g. the query object type). 20 RootObject map[string]interface{} 21 22 // A mapping of variable name to runtime value to use for all variables 23 // defined in the requestString. 24 VariableValues map[string]interface{} 25 26 // The name of the operation to use if requestString contains multiple 27 // possible operations. Can be omitted if requestString contains only 28 // one operation. 29 OperationName string 30 31 // Context may be provided to pass application-specific per-request 32 // information to resolve functions. 33 Context context.Context 34} 35 36func Do(p Params) *Result { 37 source := source.NewSource(&source.Source{ 38 Body: []byte(p.RequestString), 39 Name: "GraphQL request", 40 }) 41 42 // run init on the extensions 43 extErrs := handleExtensionsInits(&p) 44 if len(extErrs) != 0 { 45 return &Result{ 46 Errors: extErrs, 47 } 48 } 49 50 extErrs, parseFinishFn := handleExtensionsParseDidStart(&p) 51 if len(extErrs) != 0 { 52 return &Result{ 53 Errors: extErrs, 54 } 55 } 56 57 // parse the source 58 AST, err := parser.Parse(parser.ParseParams{Source: source}) 59 if err != nil { 60 // run parseFinishFuncs for extensions 61 extErrs = parseFinishFn(err) 62 63 // merge the errors from extensions and the original error from parser 64 extErrs = append(extErrs, gqlerrors.FormatErrors(err)...) 65 return &Result{ 66 Errors: extErrs, 67 } 68 } 69 70 // run parseFinish functions for extensions 71 extErrs = parseFinishFn(err) 72 if len(extErrs) != 0 { 73 return &Result{ 74 Errors: extErrs, 75 } 76 } 77 78 // notify extensions abput the start of the validation 79 extErrs, validationFinishFn := handleExtensionsValidationDidStart(&p) 80 if len(extErrs) != 0 { 81 return &Result{ 82 Errors: extErrs, 83 } 84 } 85 86 // validate document 87 validationResult := ValidateDocument(&p.Schema, AST, nil) 88 89 if !validationResult.IsValid { 90 // run validation finish functions for extensions 91 extErrs = validationFinishFn(validationResult.Errors) 92 93 // merge the errors from extensions and the original error from parser 94 extErrs = append(extErrs, validationResult.Errors...) 95 return &Result{ 96 Errors: extErrs, 97 } 98 } 99 100 // run the validationFinishFuncs for extensions 101 extErrs = validationFinishFn(validationResult.Errors) 102 if len(extErrs) != 0 { 103 return &Result{ 104 Errors: extErrs, 105 } 106 } 107 108 return Execute(ExecuteParams{ 109 Schema: p.Schema, 110 Root: p.RootObject, 111 AST: AST, 112 OperationName: p.OperationName, 113 Args: p.VariableValues, 114 Context: p.Context, 115 }) 116} 117