...
1 package transport
2
3 import (
4 "fmt"
5 "io"
6 "mime"
7 "net/http"
8 "strings"
9
10 "github.com/vektah/gqlparser/v2/gqlerror"
11
12 "github.com/99designs/gqlgen/graphql"
13 )
14
15
16
17 type POST struct {
18
19
20 ResponseHeaders map[string][]string
21 }
22
23 var _ graphql.Transport = POST{}
24
25 func (h POST) Supports(r *http.Request) bool {
26 if r.Header.Get("Upgrade") != "" {
27 return false
28 }
29
30 mediaType, _, err := mime.ParseMediaType(r.Header.Get("Content-Type"))
31 if err != nil {
32 return false
33 }
34
35 return r.Method == "POST" && mediaType == "application/json"
36 }
37
38 func getRequestBody(r *http.Request) (string, error) {
39 if r == nil || r.Body == nil {
40 return "", nil
41 }
42 body, err := io.ReadAll(r.Body)
43 if err != nil {
44 return "", fmt.Errorf("unable to get Request Body %w", err)
45 }
46 return string(body), nil
47 }
48
49 func (h POST) Do(w http.ResponseWriter, r *http.Request, exec graphql.GraphExecutor) {
50 ctx := r.Context()
51 writeHeaders(w, h.ResponseHeaders)
52 params := &graphql.RawParams{}
53 start := graphql.Now()
54 params.Headers = r.Header
55 params.ReadTime = graphql.TraceTiming{
56 Start: start,
57 End: graphql.Now(),
58 }
59
60 bodyString, err := getRequestBody(r)
61 if err != nil {
62 gqlErr := gqlerror.Errorf("could not get json request body: %+v", err)
63 resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
64 writeJson(w, resp)
65 return
66 }
67
68 bodyReader := io.NopCloser(strings.NewReader(bodyString))
69 if err = jsonDecode(bodyReader, ¶ms); err != nil {
70 w.WriteHeader(http.StatusBadRequest)
71 gqlErr := gqlerror.Errorf(
72 "json request body could not be decoded: %+v body:%s",
73 err,
74 bodyString,
75 )
76 resp := exec.DispatchError(ctx, gqlerror.List{gqlErr})
77 writeJson(w, resp)
78 return
79 }
80
81 rc, OpErr := exec.CreateOperationContext(ctx, params)
82 if OpErr != nil {
83 w.WriteHeader(statusFor(OpErr))
84 resp := exec.DispatchError(graphql.WithOperationContext(ctx, rc), OpErr)
85 writeJson(w, resp)
86 return
87 }
88
89 var responses graphql.ResponseHandler
90 responses, ctx = exec.DispatchOperation(ctx, rc)
91 writeJson(w, responses(ctx))
92 }
93
View as plain text