-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclient.go
138 lines (123 loc) · 2.85 KB
/
client.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
package rest
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"log"
"net/http"
)
type Httpmethod int
const (
GET Httpmethod = iota
POST
PUT
DELETE
)
// An HTTP request
type Request struct {
Method Httpmethod
Headers map[string]string
Url string
Data []byte
}
func (r *Request) AddHeader(k, v string) {
if r.Headers == nil {
r.Headers = make(map[string]string)
}
r.Headers[k] = v
}
// Send Request
func (r Request) Do(v interface{}) error {
var req *http.Request
var err error
switch r.Method {
case GET:
req, err = http.NewRequest("GET", r.Url, nil)
case POST:
req, err = http.NewRequest("POST", r.Url, bytes.NewBuffer(r.Data))
case PUT:
req, err = http.NewRequest("PUT", r.Url, bytes.NewBuffer(r.Data))
case DELETE:
req, err = http.NewRequest("DELETE", r.Url, nil)
}
if err != nil {
return err
}
for k, v := range r.Headers {
req.Header.Add(k, v)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
return parseResp(resp, &v)
}
// Parse a json http response into a struc and closes the Body.
func parseResp(resp *http.Response, output interface{}) error {
defer resp.Body.Close()
if resp.StatusCode >= 400 {
body, _ := ioutil.ReadAll(resp.Body)
var errResp interface{}
json.Unmarshal(body, &errResp)
return errors.New(fmt.Sprintf("Http error status code %d\n%s\n",
resp.StatusCode, errResp))
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
err = json.Unmarshal(body, &output)
if err != nil {
return err
}
return nil
}
// Make a http json-encoded POST using input struct as data and parses response into output struct.
// Input struct is encoded as JSON.
// HTTP headers, hdrs, are optional.
func Post(url string, hdrs map[string]string, input interface{}, output interface{}) error {
data, err := json.Marshal(input)
if err != nil {
log.Printf("Failed to marshal data %s", data)
return err
}
r := Request{
Method: POST,
Headers: hdrs,
Url: url,
Data: data,
}
r.AddHeader("Content-Type", "application/json")
return r.Do(&output)
}
// Make a http json-encoded PUT using input struct as data and parses response into output struct.
// Input struct is encoded as JSON.
// HTTP headers, hdrs, are optional.
func Put(url string, hdrs map[string]string, input interface{}, output interface{}) error {
data, err := json.Marshal(input)
if err != nil {
log.Printf("Failed to marshal data %s", data)
return err
}
r := Request{
Method: PUT,
Headers: hdrs,
Url: url,
Data: data,
}
r.AddHeader("Content-Type", "application/json")
return r.Do(&output)
}
// Make a GET request parses response into output struct.
// HTTP headers, hdrs, are optional.
func Get(url string, hdrs map[string]string, output interface{}) error {
r := Request{
Method: GET,
Headers: hdrs,
Url: url,
}
return r.Do(&output)
}