X Tutup
Skip to content

Commit fa3e25b

Browse files
committed
Serialize GraphQL parameters under variables
1 parent 1609afe commit fa3e25b

File tree

1 file changed

+63
-5
lines changed

1 file changed

+63
-5
lines changed

api/client.go

Lines changed: 63 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"io/ioutil"
99
"net/http"
10+
"net/url"
1011
"regexp"
1112
"strings"
1213

@@ -212,15 +213,23 @@ func (c Client) DirectRequest(method string, p string, params interface{}, heade
212213
url := "https://api.github.com/" + p
213214
var body io.Reader
214215
var bodyIsJSON bool
216+
isGraphQL := p == "graphql"
215217

216218
switch pp := params.(type) {
217219
case map[string]interface{}:
218-
b, err := json.Marshal(pp)
219-
if err != nil {
220-
return nil, fmt.Errorf("error serializing parameters: %w", err)
220+
if strings.EqualFold(method, "GET") {
221+
url = addQuery(url, pp)
222+
} else {
223+
if isGraphQL {
224+
pp = groupGraphQLVariables(pp)
225+
}
226+
b, err := json.Marshal(pp)
227+
if err != nil {
228+
return nil, fmt.Errorf("error serializing parameters: %w", err)
229+
}
230+
body = bytes.NewBuffer(b)
231+
bodyIsJSON = true
221232
}
222-
body = bytes.NewBuffer(b)
223-
bodyIsJSON = true
224233
case io.Reader:
225234
body = pp
226235
default:
@@ -246,6 +255,55 @@ func (c Client) DirectRequest(method string, p string, params interface{}, heade
246255
return c.http.Do(req)
247256
}
248257

258+
func groupGraphQLVariables(params map[string]interface{}) map[string]interface{} {
259+
topLevel := make(map[string]interface{})
260+
variables := make(map[string]interface{})
261+
262+
for key, val := range params {
263+
switch key {
264+
case "query":
265+
topLevel[key] = val
266+
default:
267+
variables[key] = val
268+
}
269+
}
270+
271+
if len(variables) > 0 {
272+
topLevel["variables"] = variables
273+
}
274+
return topLevel
275+
}
276+
277+
func addQuery(path string, params map[string]interface{}) string {
278+
if len(params) == 0 {
279+
return path
280+
}
281+
282+
query := url.Values{}
283+
for key, value := range params {
284+
switch v := value.(type) {
285+
case string:
286+
query.Add(key, v)
287+
case []byte:
288+
query.Add(key, string(v))
289+
case nil:
290+
query.Add(key, "")
291+
case int:
292+
query.Add(key, fmt.Sprintf("%d", v))
293+
case bool:
294+
query.Add(key, fmt.Sprintf("%v", v))
295+
default:
296+
panic(fmt.Sprintf("unknown type %v", v))
297+
}
298+
}
299+
300+
sep := "?"
301+
if strings.ContainsRune(path, '?') {
302+
sep = "&"
303+
}
304+
return path + sep + query.Encode()
305+
}
306+
249307
func handleResponse(resp *http.Response, data interface{}) error {
250308
success := resp.StatusCode >= 200 && resp.StatusCode < 300
251309

0 commit comments

Comments
 (0)
X Tutup