diff --git a/.gitignore b/.gitignore index f3cceee..ab970ef 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ app *.swp *.test *.out +.DS_Store diff --git a/README.md b/README.md index afa4aae..54719ee 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,11 @@ func main() { var data interface{} err = gotoolbox.HttpGetJSON("https://api.example.com/data.json", &data) - err = gotoolbox.HttpPostJSON("https://api.example.com/data.json", data, http.StatusOK) + + err = gotoolbox.HttpPutJSON("https://api.example.com/data.json", data) + + var res Response + err = gotoolbox.HttpPostJSON("https://api.example.com/data.json", data, &res, http.StatusCreated) } ``` diff --git a/json.go b/json.go index 6c8fc56..6a2f534 100644 --- a/json.go +++ b/json.go @@ -9,6 +9,9 @@ import ( "os" ) +const contentType = "Content-Type" +const contentTypeJSON = "application/json" + //ReadJSONFile reads JSON from a file func ReadJSONFile(fileName string) (map[string]string, error) { @@ -51,7 +54,7 @@ func HttpGetJSON(url string, result interface{}) error { } // HttpPutJSON encodes a struct as JSON and -// HTTP PUTs it to the specified endpoint +// HTTP PUTs it to the specified url // returns an error if http response code is not 200 func HttpPutJSON(url string, o interface{}) error { @@ -61,7 +64,7 @@ func HttpPutJSON(url string, o interface{}) error { if err != nil { return err } - req.Header.Set("Content-Type", "application/json") + req.Header.Set(contentType, contentTypeJSON) client := &http.Client{} resp, err := client.Do(req) if err != nil { @@ -75,25 +78,35 @@ func HttpPutJSON(url string, o interface{}) error { } // HttpPostJSON encodes a struct as JSON and -// HTTP POSTs it to the specified endpoint -// returns an error if http response code does not match specified -func HttpPostJSON(url string, o interface{}, httpStatusCodeToCheck int) error { +// HTTP POSTs it to the specified url. +// If the HTTP response's content-type is JSON, +// then the response is decoded into the given result. +// Returns an error if http response code does not match +// specified `httpStatusCodeToCheck`. +// Set `httpStatusCodeToCheck` == 0 to opt out of the check. +func HttpPostJSON(url string, request, response interface{}, httpStatusCodeToCheck int) error { payload := new(bytes.Buffer) - json.NewEncoder(payload).Encode(o) + json.NewEncoder(payload).Encode(request) req, err := http.NewRequest(http.MethodPost, url, payload) if err != nil { return err } - req.Header.Set("Content-Type", "application/json") + req.Header.Set(contentType, contentTypeJSON) client := &http.Client{} resp, err := client.Do(req) if err != nil { return fmt.Errorf("unexpected http PUT error: %w", err) } defer resp.Body.Close() - if resp.StatusCode != httpStatusCodeToCheck { + if resp.StatusCode != 0 && resp.StatusCode != httpStatusCodeToCheck { return fmt.Errorf("unexpected http POST status: %s", resp.Status) } + if resp.Header.Get(contentType) == contentTypeJSON { + err = json.NewDecoder(resp.Body).Decode(response) + if err != nil { + return fmt.Errorf("cannot decode JSON: %w", err) + } + } return nil }