Skip to content

Instantly share code, notes, and snippets.

@visola
Created March 2, 2018 13:25
Show Gist options
  • Save visola/5359a3993c4f06d860ff192f1405c490 to your computer and use it in GitHub Desktop.
Save visola/5359a3993c4f06d860ff192f1405c490 to your computer and use it in GitHub Desktop.
Refactoring HTTP Request execution
package main
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
"net/http/httputil"
)
type authRequest struct {
UserName string `json:"username"`
Password string `json:"password"`
}
type authResponse struct {
Token string
}
type configRequest struct {
ID string `json:"id"`
}
type configResponse struct {
Foo string
}
// HTTP Bin post method returns the posted body in a data attribute
type httpBinResponse struct {
Data string `json:"data"`
}
func main() {
token, err := getAuthToken()
if err != nil {
log.Fatal(err)
}
config, err := getConfig("foo", token)
if err != nil {
log.Fatal(err)
}
_ = config
}
func buildRequest(endpoint string, body interface{}, extraHeaders map[string]string) (*http.Request, error) {
jsnBytes, err := json.Marshal(body)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", endpoint, bytes.NewReader(jsnBytes))
if err != nil {
return nil, err
}
req.Header.Add("Content-Type", "application/json")
for name, value := range extraHeaders {
req.Header.Add(name, value)
}
dump, err := httputil.DumpRequest(req, true)
if err != nil {
return nil, err
}
log.Println("Request: ", string(dump))
return req, nil
}
func executeRequest(req *http.Request, responseBody interface{}) error {
client := http.Client{}
log.Println("Initiating http request")
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
bytes, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
log.Printf("Response is: %s\n", string(bytes))
var httpBinJSON httpBinResponse
err = json.Unmarshal(bytes, &httpBinJSON)
log.Printf("Unmarshalled response: %s\n", httpBinJSON)
return err
}
func getAuthToken() (string, error) {
endpoint := "https://httpbin.org/post"
req, err := buildRequest(endpoint, authRequest{
UserName: "foo",
Password: "bar",
}, nil)
if err != nil {
return "", err
}
var resp authResponse
return "", executeRequest(req, &resp)
}
func getConfig(id string, token string) (*configResponse, error) {
endpoint := "https://httpbin.org/post"
req, err := buildRequest(endpoint, configRequest{ID: id}, map[string]string{
"Authorization": "Bearer " + token,
})
if err != nil {
return nil, err
}
var config configResponse
err = executeRequest(req, config)
if err != nil {
return nil, err
}
return &config, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment