Last active
November 22, 2019 06:42
-
-
Save quells/cde33b128b0d1555641b322acca583b4 to your computer and use it in GitHub Desktop.
Basic Go HTTP helper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package rex | |
import ( | |
"bytes" | |
"net/http" | |
"strings" | |
"time" | |
) | |
type Request struct { | |
method, baseURL, path string | |
headers map[string][]string | |
params map[string]string | |
body []byte | |
} | |
func newRequest(method, baseURL, path string) *Request { | |
return &Request{ | |
method: method, | |
baseURL: baseURL, | |
path: path, | |
headers: make(map[string][]string), | |
params: make(map[string]string), | |
} | |
} | |
func Get(baseURL, path string) *Request { | |
return newRequest(http.MethodGet, baseURL, path) | |
} | |
func Post(baseURL, path string) *Request { | |
return newRequest(http.MethodPost, baseURL, path) | |
} | |
func Put(baseURL, path string) *Request { | |
return newRequest(http.MethodPut, baseURL, path) | |
} | |
func Delete(baseURL, path string) *Request { | |
return newRequest(http.MethodDelete, baseURL, path) | |
} | |
func (r *Request) Header(header string, values ...string) *Request { | |
r.headers[header] = append(r.headers[header], values...) | |
return r | |
} | |
func (r *Request) BasicAuth(username, password string) *Request { | |
value := base64.StdEncoding.EncodeToString([]byte(username + ":" + password)) | |
return r.Header("Authorization", "Basic "+value) | |
} | |
func (r *Request) Param(key, value string) *Request { | |
r.params[key] = value | |
return r | |
} | |
func (r *Request) Params(params map[string]string) *Request { | |
for k, v := range params { | |
r.params[k] = v | |
} | |
return r | |
} | |
func (r *Request) Body(body []byte) *Request { | |
r.body = body | |
return r | |
} | |
func (r Request) buildRequest() (req *http.Request, err error) { | |
baseURL := r.baseURL + r.path | |
queryParams := make([]string, len(r.params)) | |
var i int | |
for k, v := range r.params { | |
queryParams[i] = k + "=" + v | |
i++ | |
} | |
u := baseURL + "?" + strings.Join(queryParams, "&") | |
if len(r.body) > 0 { | |
buf := bytes.NewBuffer(r.body) | |
req, err = http.NewRequest(r.method, u, buf) | |
} else { | |
req, err = http.NewRequest(r.method, u, nil) | |
} | |
if err != nil { | |
return | |
} | |
for header, values := range r.headers { | |
for _, value := range values { | |
req.Header.Add(header, value) | |
} | |
} | |
return | |
} | |
func (r Request) Send() (resp *http.Response, stats *Stats, err error) { | |
var req *http.Request | |
req, err = r.buildRequest() | |
if err != nil { | |
return | |
} | |
stats = NewStats() | |
resp, err = http.DefaultClient.Do(req) | |
stats.done() | |
if err == nil { | |
stats.StatusCode = resp.StatusCode | |
} | |
return | |
} | |
func (r Request) IntoJSON(v interface{}) (stats *Stats, err error) { | |
var resp *http.Response | |
resp, stats, err = r.Send() | |
if err != nil { | |
return | |
} | |
var respData []byte | |
respData, err = ioutil.ReadAll(resp.Body) | |
resp.Body.Close() | |
if err != nil { | |
return | |
} | |
err = json.Unmarshal(respData, v) | |
return | |
} | |
func (r Request) JSON() (respBody map[string]interface{}, stats *Stats, err error) { | |
stats, err = r.IntoJSON(&respBody) | |
return | |
} | |
// Stats about a Request. | |
type Stats struct { | |
StatusCode int | |
Start time.Time | |
Duration time.Duration | |
} | |
func NewStats() *Stats { | |
return &Stats{ | |
Start: time.Now(), | |
} | |
} | |
func (s *Stats) done() { | |
s.Duration = time.Since(s.Start) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment