-
Notifications
You must be signed in to change notification settings - Fork 0
/
icp.go
130 lines (122 loc) · 2.98 KB
/
icp.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
package icp
import (
"bytes"
"context"
"encoding/json"
"errors"
"io"
"net/http"
"net/url"
"github.com/google/go-querystring/query"
)
// ICP holds the projectID, endpoint and http client for the configured
// ICP instance. If token is set it is sent with each request as a auth header.
type ICP struct {
BaseURL string
client *http.Client
token string
}
// ErrServerError makes it a little easier for the caller to check the
// underlying HTTP response
var ErrServerError = errors.New("Error from server (HTTP Status > 299)")
// New returns a new ICP object. BaseURL defaults to
// "https://icp-api.itrsgroup.com/v2.0" and client, if nil, to a default
// http.Client
func New(options ...Options) (icp *ICP) {
opts := evalOptions(options...)
icp = &ICP{
BaseURL: opts.baseURL,
client: opts.client,
}
return
}
// Post makes a POST request to the endpoint after marshalling the body
// as json. The caller must close resp.Body.
func (icp *ICP) Post(ctx context.Context, endpoint string, request interface{}) (resp *http.Response, err error) {
dest, err := url.JoinPath(icp.BaseURL, endpoint)
if err != nil {
return
}
j, err := json.Marshal(request)
if err != nil {
return
}
req, err := http.NewRequestWithContext(ctx, "POST", dest, bytes.NewReader(j))
if err != nil {
return
}
if icp.token != "" {
req.Header.Add("Authorization", "SUMERIAN "+icp.token)
}
req.Header.Add("content-type", "application/json")
return icp.client.Do(req)
}
// Get sends a GET request to the endpoint
func (icp *ICP) Get(ctx context.Context, endpoint string, request interface{}, response interface{}) (resp *http.Response, err error) {
dest, err := url.JoinPath(icp.BaseURL, endpoint)
if err != nil {
return
}
req, err := http.NewRequestWithContext(ctx, "GET", dest, nil)
if err != nil {
return
}
if icp.token != "" {
req.Header.Add("Authorization", "SUMERIAN "+icp.token)
}
if request != nil {
v, err := query.Values(request)
if err != nil {
return resp, err
}
req.URL.RawQuery = v.Encode()
}
resp, err = icp.client.Do(req)
if resp.StatusCode > 299 {
err = ErrServerError
return
}
defer resp.Body.Close()
if response == nil {
return
}
switch t := response.(type) {
case string:
var b []byte
b, err = io.ReadAll(resp.Body)
t = string(b)
default:
d := json.NewDecoder(resp.Body)
err = d.Decode(&t)
}
return
}
// Delete Method
func (icp *ICP) Delete(ctx context.Context, endpoint string, request interface{}) (resp *http.Response, err error) {
dest, err := url.JoinPath(icp.BaseURL, endpoint)
if err != nil {
return
}
req, err := http.NewRequestWithContext(ctx, "DELETE", dest, nil)
if err != nil {
return
}
if icp.token != "" {
req.Header.Add("Authorization", "SUMERIAN "+icp.token)
}
if request != nil {
v, err := query.Values(request)
if err != nil {
return resp, err
}
req.URL.RawQuery = v.Encode()
}
resp, err = icp.client.Do(req)
if resp.StatusCode > 299 {
err = ErrServerError
return
}
// discard any body
resp.Body.Close()
return
}