-
Notifications
You must be signed in to change notification settings - Fork 4
/
request.go
134 lines (111 loc) · 2.64 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
package listmonk
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"reflect"
"strings"
)
// request define an API request
type request struct {
method string
endpoint string
query url.Values
json map[string]interface{}
header http.Header
body io.Reader
}
// setParam set param with key/value to query string
func (r *request) setParam(key string, value interface{}) *request {
if r.query == nil {
r.query = url.Values{}
}
if reflect.TypeOf(value).Kind() == reflect.Slice {
v, err := json.Marshal(value)
if err == nil {
value = string(v)
}
}
r.query.Set(key, fmt.Sprintf("%v", value))
return r
}
func (r *request) setParamList(baseParam string, params ...interface{}) *request {
for index, value := range params {
r.setParam(fmt.Sprintf("%s[%d]", baseParam, index), value)
}
return r
}
// setFormParam set param with key/value to request form body
func (r *request) setJsonParam(key string, value interface{}) *request {
if r.json == nil {
r.json = map[string]interface{}{}
}
r.json[key] = value
return r
}
func (r *request) validate() {
if r.query == nil {
r.query = url.Values{}
}
if r.json == nil {
r.json = map[string]interface{}{}
}
if r.header == nil {
r.header = http.Header{}
}
}
func (r *request) toHttpRequest(baseUrl string, username, password *string, ctx context.Context, opts ...requestOption) (req *http.Request, err error) {
r.validate()
var body io.Reader
if r.json != nil {
jsonBytes, err := json.Marshal(r.json)
if err != nil {
return nil, err
}
body = bytes.NewReader(jsonBytes)
r.header.Set("Content-Type", "application/json")
}
req, err = http.NewRequest(r.method, fmt.Sprintf("%s/api/%s", baseUrl, strings.TrimPrefix(r.endpoint, "/")), body)
if err != nil {
return nil, err
}
req.URL.RawQuery = r.query.Encode()
if username != nil && password != nil {
req.SetBasicAuth(*username, *password)
}
for key, values := range r.header {
for _, value := range values {
req.Header.Add(key, value)
}
}
for _, opt := range opts {
opt(r)
}
req = req.WithContext(ctx)
return req, nil
}
// RequestOption define option type for request
type requestOption func(*request)
// WithHeader set or add a header value to the request
func WithHeader(key, value string, replace bool) requestOption {
return func(r *request) {
if r.header == nil {
r.header = http.Header{}
}
if replace {
r.header.Set(key, value)
} else {
r.header.Add(key, value)
}
}
}
// WithHeaders set or replace the headers of the request
func WithHeaders(header http.Header) requestOption {
return func(r *request) {
r.header = header.Clone()
}
}