github.com/fortexxx/gqlgen@v0.10.3-0.20191216030626-ca5ea8b21ead/graphql/handler/transport/http_get.go (about) 1 package transport 2 3 import ( 4 "encoding/json" 5 "io" 6 "net/http" 7 "strings" 8 9 "github.com/99designs/gqlgen/graphql" 10 "github.com/vektah/gqlparser/ast" 11 ) 12 13 // GET implements the GET side of the default HTTP transport 14 // defined in https://github.com/APIs-guru/graphql-over-http#get 15 type GET struct{} 16 17 var _ graphql.Transport = GET{} 18 19 func (h GET) Supports(r *http.Request) bool { 20 if r.Header.Get("Upgrade") != "" { 21 return false 22 } 23 24 return r.Method == "GET" 25 } 26 27 func (h GET) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) { 28 raw := &graphql.RawParams{ 29 Query: r.URL.Query().Get("query"), 30 OperationName: r.URL.Query().Get("operationName"), 31 } 32 33 if variables := r.URL.Query().Get("variables"); variables != "" { 34 if err := jsonDecode(strings.NewReader(variables), &raw.Variables); err != nil { 35 w.WriteHeader(http.StatusBadRequest) 36 writeJsonError(w, "variables could not be decoded") 37 return 38 } 39 } 40 41 if extensions := r.URL.Query().Get("extensions"); extensions != "" { 42 if err := jsonDecode(strings.NewReader(extensions), &raw.Extensions); err != nil { 43 w.WriteHeader(http.StatusBadRequest) 44 writeJsonError(w, "extensions could not be decoded") 45 return 46 } 47 } 48 49 rc, err := exec.CreateOperationContext(r.Context(), raw) 50 if err != nil { 51 w.WriteHeader(http.StatusUnprocessableEntity) 52 resp := exec.DispatchError(graphql.WithOperationContext(r.Context(), rc), err) 53 writeJson(w, resp) 54 return 55 } 56 op := rc.Doc.Operations.ForName(rc.OperationName) 57 if op.Operation != ast.Query { 58 w.WriteHeader(http.StatusNotAcceptable) 59 writeJsonError(w, "GET requests only allow query operations") 60 return 61 } 62 63 responses, ctx := exec.DispatchOperation(r.Context(), rc) 64 writeJson(w, responses(ctx)) 65 } 66 67 func jsonDecode(r io.Reader, val interface{}) error { 68 dec := json.NewDecoder(r) 69 dec.UseNumber() 70 return dec.Decode(val) 71 }