The "net/http" golang package has a response type which I find confusing. It defines a member Body io.ReadCloser which requires an additional call to some form of an io writer to process. Why did the developers not choose to make the Body a []bytes or a string? These seem like much more obvious, natural choices to me.
-
3An io.Reader is the far more natural choice in Go as these interfaces combine. From a technical perspective using []bytes is bad as it doesn't allow any type of streaming.Volker– Volker2023-12-09 09:16:55 +00:00Commented Dec 9, 2023 at 9:16
1 Answer
An HTTP response body is a stream of bytes on the network connection. The io.Reader type is Go's representation of a stream of bytes. The Response.Body field is typed as io.ReadCloser which is an io.Reader with a Close() method.
An advantage of io.Reader over string and []byte is that the application can stream through the response without loading the entire response in memory.
Use io.ReadAll to read the io.Reader's data to a []byte.
Here's a convenient helper function converting the (*http.Response, error) return values from the net/http functions to a []byte:
func bodyBytes(r *http.Response, err error) (*http.Response, []byte, error) {
if err != nil {
return r, nil, err
}
b, err := io.ReadAll(r.Body)
r.Body.Close()
return r, b, err
}
Use the function like this:
r, b, err := bodyBytes(http.Get("http://example.com"))
if err != nil {
// insert error handling here
}
// r is an *http.Response, with closed body
// b is a []byte containing the body