-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
core.go
134 lines (112 loc) · 2.67 KB
/
core.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
package mono
import (
"context"
"encoding/json"
"errors"
"io"
"io/ioutil"
"net/http"
"net/url"
"path"
"time"
)
// DefaultBaseURL is production URL of Monobank API.
const DefaultBaseURL = "https://api.monobank.ua"
type core struct {
http.Client
baseURL string
}
func (c *core) buildURL(endpoint string) (string, error) {
baseURL, err := url.Parse(c.baseURL)
if err != nil {
return "", err
}
baseURL.Path = path.Join(baseURL.Path, endpoint)
return baseURL.String(), nil
}
// newCore creates a new MonoBank client with some reasonable HTTP request defaults.
func newCore() *core {
return &core{
baseURL: DefaultBaseURL,
Client: http.Client{
Timeout: time.Second * 5,
Transport: &http.Transport{
MaxIdleConns: 50,
MaxIdleConnsPerHost: 50,
},
},
}
}
// GetJSON builds the full endpoint path and gets the raw JSON.
func (c *core) GetJSON(ctx context.Context, endpoint string, headers map[string]string) ([]byte, int, error) {
uri, err := c.buildURL(endpoint)
if err != nil {
return nil, 0, err
}
r, err := http.NewRequestWithContext(ctx, "GET", uri, nil)
if err != nil {
return nil, 0, err
}
// Set headers.
for k, v := range headers {
r.Header.Set(k, v)
}
resp, err := c.Do(r)
if err != nil {
return nil, 0, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
return body, resp.StatusCode, err
}
// PostJSON builds the full endpoint path and gets the raw JSON.
func (c *core) PostJSON(
ctx context.Context,
endpoint string,
headers map[string]string,
payload io.Reader,
) ([]byte, int, error) {
uri, err := c.buildURL(endpoint)
if err != nil {
return nil, 0, err
}
r, err := http.NewRequestWithContext(ctx, "POST", uri, payload)
if err != nil {
return nil, 0, err
}
// Set headers.
for k, v := range headers {
r.Header.Set(k, v)
}
resp, err := c.Do(r)
if err != nil {
return nil, 0, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
return body, resp.StatusCode, err
}
// Rates returns list of currencies rates from MonoBank API.
// See https://api.monobank.ua/docs/#/definitions/CurrencyInfo for details.
func (c *core) Rates(ctx context.Context) ([]Exchange, error) {
contents, status, err := c.GetJSON(ctx, "/bank/currency", nil)
if err != nil {
return nil, err
}
if status != http.StatusOK {
var msg Error
if err := json.Unmarshal(contents, &msg); err != nil {
return nil, errors.New("invalid error payload")
}
return nil, msg
}
var data []Exchange
if err = json.Unmarshal(contents, &data); err != nil {
return nil, err
}
return data, nil
}
// SetBaseURL set baseURL to the new specified URL.
func (c *core) SetBaseURL(url string) {
c.baseURL = url
}