-
Notifications
You must be signed in to change notification settings - Fork 9
/
request.go
145 lines (116 loc) · 3.09 KB
/
request.go
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package convoy_go
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/http/httputil"
)
func postJSON(ctx context.Context, c *Client, url string, body interface{}, res interface{}) error {
buf, err := json.Marshal(body)
if err != nil {
return err
}
payload := bytes.NewBuffer(buf)
req, err := http.NewRequestWithContext(ctx, http.MethodPost, url, payload)
if err != nil {
return err
}
return doReq(c, req, res)
}
func putResource(ctx context.Context, c *Client, url string, body interface{}, res interface{}) error {
if body == nil {
body = `{}`
}
buf, err := json.Marshal(body)
if err != nil {
return err
}
payload := bytes.NewBuffer(buf)
req, err := http.NewRequestWithContext(ctx, http.MethodPut, url, payload)
if err != nil {
return err
}
return doReq(c, req, res)
}
func getResource(ctx context.Context, c *Client, url string, res interface{}) error {
req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil)
if err != nil {
return err
}
return doReq(c, req, res)
}
func deleteResource(ctx context.Context, c *Client, url string, res interface{}) error {
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, url, nil)
if err != nil {
return err
}
return doReq(c, req, res)
}
func doReq(c *Client, req *http.Request, res interface{}) error {
req.Header.Add("Content-Type", "application/json;charset=utf-8")
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiKey))
req.Header.Set("X-Convoy-Version", "0001-01-01")
resp, err := c.client.Do(req)
if err != nil {
return fmt.Errorf("error processing request - %+v", err)
}
// Send debug logs.
dump, err := httputil.DumpRequestOut(req, true)
if err != nil {
c.log.Errorf("error dumping request payload - ", err)
}
c.log.Debugf("request: %q", dump)
err = parseAPIResponse(c, resp, res)
if err != nil {
return err
}
return nil
}
func parseAPIResponse(c *Client, resp *http.Response, resultPtr interface{}) error {
// Send debug logs.
dump, err := httputil.DumpResponse(resp, true)
if err != nil {
c.log.Errorf("error dumping response payload - ", err)
}
c.log.Debugf("response: %q", dump)
b, err := io.ReadAll(resp.Body)
if err != nil {
return fmt.Errorf("error while reading the response bytes - %+v", err)
}
defer func() {
err := resp.Body.Close()
if err != nil {
c.log.Errorf("error closing response body - ", err)
}
}()
var response APIResponse
err = json.Unmarshal(b, &response)
if err != nil {
return fmt.Errorf("error while unmarshalling the response bytes %+v ", err)
}
if !response.Status && invalidStatusCode(resp.StatusCode) {
return fmt.Errorf("convoy error: %s", response.Message)
}
if resultPtr != nil {
err = json.Unmarshal(*response.Data, resultPtr)
if err != nil {
return fmt.Errorf("error while unmarshalling the response data bytes %+v ", err)
}
}
return nil
}
func invalidStatusCode(actual int) bool {
//Valid list of good HTTP response codes to expect from Convoy's API
expected := map[int]bool{
200: true,
202: true,
204: true,
}
if _, ok := expected[actual]; ok {
return false
}
return true
}