diff --git a/README.md b/README.md index 49d5935..bff0458 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ type MyResponse struct { // ... } -func (r *MyResponse) Decode(body io.ReadCloser) error { +func (r *MyResponse) Decode(body io.Reader) error { // Decode the response body into the response model } diff --git a/examples/cmd/context/main.go b/examples/cmd/context/main.go index 5b59ced..62b6f72 100644 --- a/examples/cmd/context/main.go +++ b/examples/cmd/context/main.go @@ -36,12 +36,13 @@ type TodoResponse struct { Comleted bool `json:"completed"` } -func (r *TodoResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *TodoResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *TodoResponse) SetBody(body io.Reader) { +func (r *TodoResponse) SetBody(body io.Reader) error { + return nil } @@ -49,8 +50,9 @@ func (r *TodoResponse) AcceptContentType() string { return "application/json" } -func (r *TodoResponse) SetStatusCode(code int) { +func (r *TodoResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/delete/main.go b/examples/cmd/delete/main.go index 58d871c..856c46a 100644 --- a/examples/cmd/delete/main.go +++ b/examples/cmd/delete/main.go @@ -31,19 +31,22 @@ type DeletePostResponse struct { HTTPStatusCode int `json:"-"` } -func (r *DeletePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *DeletePostResponse) Decode(body io.Reader) error { + return nil } -func (r *DeletePostResponse) SetBody(body io.Reader) {} +func (r *DeletePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *DeletePostResponse) AcceptContentType() string { return "" } -func (r *DeletePostResponse) SetStatusCode(code int) { +func (r *DeletePostResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/get/main.go b/examples/cmd/get/main.go index 740309a..8624cc3 100644 --- a/examples/cmd/get/main.go +++ b/examples/cmd/get/main.go @@ -35,19 +35,22 @@ type TodoResponse struct { Comleted bool `json:"completed"` } -func (r *TodoResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *TodoResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *TodoResponse) SetBody(body io.Reader) {} +func (r *TodoResponse) SetBody(body io.Reader) error { + return nil +} func (r *TodoResponse) AcceptContentType() string { return "application/json" } -func (r *TodoResponse) SetStatusCode(code int) { +func (r *TodoResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/patch/main.go b/examples/cmd/patch/main.go index 6c8dbe2..e7bfee3 100644 --- a/examples/cmd/patch/main.go +++ b/examples/cmd/patch/main.go @@ -44,19 +44,22 @@ type UpdatePostResponse struct { Body string `json:"body,omitempty"` } -func (r *UpdatePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *UpdatePostResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *UpdatePostResponse) SetBody(body io.Reader) {} +func (r *UpdatePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *UpdatePostResponse) AcceptContentType() string { return "application/json" } -func (r *UpdatePostResponse) SetStatusCode(code int) { +func (r *UpdatePostResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/post/main.go b/examples/cmd/post/main.go index 8a91f5e..ccee31b 100644 --- a/examples/cmd/post/main.go +++ b/examples/cmd/post/main.go @@ -43,19 +43,22 @@ type CreatePostResponse struct { Body string `json:"body"` } -func (r *CreatePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *CreatePostResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *CreatePostResponse) SetBody(body io.Reader) {} +func (r *CreatePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *CreatePostResponse) AcceptContentType() string { return "application/json" } -func (r *CreatePostResponse) SetStatusCode(code int) { +func (r *CreatePostResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/put/main.go b/examples/cmd/put/main.go index a010f40..cd98143 100644 --- a/examples/cmd/put/main.go +++ b/examples/cmd/put/main.go @@ -44,19 +44,22 @@ type UpdatePostResponse struct { Body string `json:"body"` } -func (r *UpdatePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *UpdatePostResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *UpdatePostResponse) SetBody(body io.Reader) {} +func (r *UpdatePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *UpdatePostResponse) AcceptContentType() string { return "application/json" } -func (r *UpdatePostResponse) SetStatusCode(code int) { +func (r *UpdatePostResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/examples/cmd/url_values/main.go b/examples/cmd/url_values/main.go index 9a5695b..6376226 100644 --- a/examples/cmd/url_values/main.go +++ b/examples/cmd/url_values/main.go @@ -42,19 +42,22 @@ type CommentsResponse struct { } `json:"data"` } -func (r *CommentsResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *CommentsResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(&r.Data) } -func (r *CommentsResponse) SetBody(body io.Reader) {} +func (r *CommentsResponse) SetBody(body io.Reader) error { + return nil +} func (r *CommentsResponse) AcceptContentType() string { return "application/json" } -func (r *CommentsResponse) SetStatusCode(code int) { +func (r *CommentsResponse) SetStatusCode(code int) error { r.HTTPStatusCode = code + return nil } func main() { diff --git a/restclient_test.go b/restclient_test.go index f2d762a..9a158d1 100644 --- a/restclient_test.go +++ b/restclient_test.go @@ -24,13 +24,18 @@ type TodoResponse struct { func (r *todoRequest) Path() (string, error) { return "/todos/" + r.ID, nil } func (r *todoRequest) Encode() (io.Reader, error) { return nil, nil } func (r *todoRequest) ContentType() string { return "" } -func (r *TodoResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *TodoResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *TodoResponse) SetBody(body io.Reader) {} +func (r *TodoResponse) SetBody(body io.Reader) error { + return nil +} func (r *TodoResponse) AcceptContentType() string { return "application/json" } -func (r *TodoResponse) SetStatusCode(code int) { r.HTTPStatusCode = code } +func (r *TodoResponse) SetStatusCode(code int) error { + r.HTTPStatusCode = code + return nil +} //--------------------------------------------- @@ -47,13 +52,18 @@ func (r *deletePostRequest) Path() (string, error) { return "/posts/" + fmt.Spri func (r *deletePostRequest) Encode() (io.Reader, error) { return nil, nil } func (r *deletePostRequest) ContentType() string { return "" } -func (r *DeletePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *DeletePostResponse) Decode(body io.Reader) error { + + return nil +} +func (r *DeletePostResponse) SetBody(body io.Reader) error { return nil } -func (r *DeletePostResponse) SetBody(body io.Reader) {} func (r *DeletePostResponse) AcceptContentType() string { return "" } -func (r *DeletePostResponse) SetStatusCode(code int) { r.HTTPStatusCode = code } +func (r *DeletePostResponse) SetStatusCode(code int) error { + r.HTTPStatusCode = code + return nil +} // --------------------------------------------- @@ -82,13 +92,18 @@ func (r *updatePostRequest) Encode() (io.Reader, error) { return bytes.NewReader(jsonBytes), nil } func (r *updatePostRequest) ContentType() string { return "application/json; charset=UTF-8" } -func (r *UpdatePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *UpdatePostResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *UpdatePostResponse) SetBody(body io.Reader) {} +func (r *UpdatePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *UpdatePostResponse) AcceptContentType() string { return "application/json" } -func (r *UpdatePostResponse) SetStatusCode(code int) { r.HTTPStatusCode = code } +func (r *UpdatePostResponse) SetStatusCode(code int) error { + r.HTTPStatusCode = code + return nil +} // --------------------------------------------- @@ -118,13 +133,18 @@ func (r *createPostRequest) Encode() (io.Reader, error) { return bytes.NewReader(jsonBytes), nil } func (r *createPostRequest) ContentType() string { return "application/json" } -func (r *CreatePostResponse) Decode(body io.ReadCloser) error { - defer body.Close() +func (r *CreatePostResponse) Decode(body io.Reader) error { + return json.NewDecoder(body).Decode(r) } -func (r *CreatePostResponse) SetBody(body io.Reader) {} +func (r *CreatePostResponse) SetBody(body io.Reader) error { + return nil +} func (r *CreatePostResponse) AcceptContentType() string { return "application/json" } -func (r *CreatePostResponse) SetStatusCode(code int) { r.HTTPStatusCode = code } +func (r *CreatePostResponse) SetStatusCode(code int) error { + r.HTTPStatusCode = code + return nil +} // --------------------------------------------- diff --git a/restclientgo.go b/restclientgo.go index bfa7c77..dd405a7 100644 --- a/restclientgo.go +++ b/restclientgo.go @@ -49,15 +49,14 @@ type Request interface { type Response interface { // Decode decodes the response body into the given interface if the - // response is a success and the content type is json. - Decode(body io.ReadCloser) error - // SetBody sets the response raw body if the response is a success but - // the content type is not json. - SetBody(body io.Reader) + // response matches the AcceptContentType. + Decode(body io.Reader) error + // SetBody sets the response raw body if the response can't be decoded. + SetBody(body io.Reader) error // AcceptContentType returns the content type that the response should be decoded to. AcceptContentType() string // SetStatusCode sets the HTTP response status code. - SetStatusCode(code int) + SetStatusCode(code int) error } const ( @@ -140,6 +139,7 @@ func (r *RestClient) do(ctx context.Context, method httpMethod, request Request, if err != nil { return fmt.Errorf("%w: %s", ErrHTTPRequest, err) } + defer httpResponse.Body.Close() response.SetStatusCode(httpResponse.StatusCode) if httpResponse.StatusCode >= 400 {