-
Notifications
You must be signed in to change notification settings - Fork 8
/
api.go
106 lines (84 loc) · 1.91 KB
/
api.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
package geocodio
import (
"bytes"
"encoding/json"
"errors"
"fmt"
// "fmt"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
)
const (
// MethodGet constant
MethodGet = "GET"
// MethodPost constant
MethodPost = "POST"
)
type saver interface {
SaveDebug(requestedURL, status string, statusCode int, body []byte)
}
func (g *Geocodio) get(path string, query map[string]string, result saver) error {
return g.call(MethodGet, path, nil, query, result)
}
func (g *Geocodio) post(path string, payload interface{}, query map[string]string, result saver) error {
return g.call(MethodPost, path, payload, query, result)
}
func (g *Geocodio) call(method, path string, payload interface{}, query map[string]string, result saver) error {
if strings.Index(path, "/") != 0 {
return errors.New("Path must start with a forward slash: ' / ' ")
}
rawURL := GeocodioAPIBaseURLv1 + path + "?api_key=" + g.APIKey
if query != nil {
for k, v := range query {
rawURL = fmt.Sprintf("%s&%s=%s", rawURL, k, url.QueryEscape(v))
}
}
timeout := time.Duration(10 * time.Second)
client := http.Client{
Timeout: timeout,
}
u, err := url.Parse(rawURL)
if err != nil {
return nil
}
if query != nil {
for k, v := range query {
if u.Query().Get(k) != "" {
u.Query().Set(k, v)
continue
}
u.Query().Add(k, v)
}
}
req := http.Request{
Method: method,
URL: u,
Header: http.Header{},
}
if payload != nil {
body, err := json.Marshal(payload)
if err != nil {
return err
}
req.Body = ioutil.NopCloser(bytes.NewReader(body))
req.Header.Add("Content-Type", "application/json")
}
resp, err := client.Do(&req)
if err != nil {
return err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
result.SaveDebug(u.String(), resp.Status, resp.StatusCode, body)
err = json.Unmarshal(body, &result)
if err != nil {
return err
}
return nil
}