-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathGraphQL_query.ml
72 lines (70 loc) · 2.16 KB
/
GraphQL_query.ml
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
open Base
open Bot_info
open Utils
type api = GitHub | GitLab of string
let send_graphql_query ~bot_info ?(extra_headers = []) ?(ignore_errors = false)
~api ~query ~parse variables =
let uri =
( match api with
| GitLab gitlab_domain ->
f "https://%s/api/graphql" gitlab_domain
| GitHub ->
"https://api.github.com/graphql" )
|> Uri.of_string
in
let open Lwt_result.Infix in
( match api with
| GitLab gitlab_domain ->
gitlab_name_and_token bot_info gitlab_domain
| GitHub ->
Ok (bot_info.github_name, github_token bot_info) )
|> Lwt.return
>>= fun (name, token) ->
let headers =
Cohttp.Header.of_list
( [ ("Authorization", "Bearer " ^ token)
; ("User-Agent", name)
; ("Content-Type", "application/json") ]
@ extra_headers )
in
let request_json =
`Assoc [("query", `String query); ("variables", variables)]
in
let request = Yojson.Basic.to_string request_json in
let open Lwt.Infix in
Cohttp_lwt_unix.Client.post ~headers ~body:(`String request) uri
>>= fun (rsp, body) ->
Cohttp_lwt.Body.to_string body
>|= fun body ->
match Cohttp.Code.(code_of_status rsp.status |> is_success) with
| false ->
Error body
| true -> (
try
let json = Yojson.Basic.from_string body in
let open Yojson.Basic.Util in
let data = json |> member "data" |> parse in
if ignore_errors then Ok data
else
match member "errors" json with
| `Null ->
Ok data
| errors ->
let errors =
to_list errors
|> List.map ~f:(fun error ->
error |> member "message" |> to_string )
in
Error
( "Server responded to GraphQL request with errors: "
^ String.concat ~sep:", " errors )
with
| Failure err ->
Error (f "Exception: %s" err)
| Yojson.Json_error err ->
Error
(f "Json error: %s. Body was:\n%s\nRequest was:\n%s" err body request)
| Yojson.Basic.Util.Type_error (err, _) ->
Error
(f "Json type error: %s. Body was:\n%s. Request was:\n%s" err body
request ) )