How to Get HTTP Response as a String in Go: Best Practices 2025

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

«Access HTTP response as string in Go» — a question that torments beginners and pros alike

\n\n

Have you ever written an HTTP client in Go and suddenly realized you don't know how to elegantly turn the raw server response into a regular string? If so — you are not alone. The question «Access HTTP response as string in Go» on Stack Overflow gathers thousands of views, and this is no coincidence.

\n\n

Go is a language loved for its simplicity, but working with HTTP responses can confuse even an experienced developer. In 2025, best practices have changed: the old reliable ioutil.ReadAll is history, and new standard approaches have taken the stage. Let's figure out how to correctly read an HTTP response as a string, avoiding typical mistakes and following modern Go conventions.

\n\n

Why is simply «reading the response» not so simple?

\n\n

When you make an HTTP request in Go, the response comes as an object of type *http.Response. Its body (Body) is an io.ReadCloser, meaning a stream of bytes that needs to be read and interpreted. If you try to just assign it to a string, the compiler will say «no». You need to explicitly read the stream into memory, convert the bytes to a string, and don't forget to close the body.

\n\n

Here is a minimal example you will see in most tutorials (but we will improve it):

\n\n
package main\n\nimport (\n    "fmt"\n    "net/http"\n    "io"\n)\n\nfunc main() {\n    resp, err := http.Get("https://api.example.com/data")\n    if err != nil {\n        panic(err)\n    }\n    defer resp.Body.Close()\n\n    body, err := io.ReadAll(resp.Body)\n    if err != nil {\n        panic(err)\n    }\n\n    fmt.Println(string(body))\n}
\n\n

It works. But in a real project, this approach is a path to memory leaks, unreadable code, and hard-to-find bugs. Let's figure out what can be improved.

\n\n

Best Practices 2025: How to Read HTTP Response as a String Correctly

\n\n

1. Forget ioutil.ReadAll — use io.ReadAll

\n\n

If you are writing in Go version 1.16+, forget about the ioutil package. It is marked as deprecated. Instead, use io.ReadAll. This is not just a name change: io.ReadAll works faster and cleaner, and most importantly, it doesn't require importing an extra package.

\n\n
// Bad (deprecated)\nimport "io/ioutil"\nbody, _ := ioutil.ReadAll(resp.Body)\n\n// Good (modern)\nimport "io"\nbody, _ := io.ReadAll(resp.Body)
\n\n

2. Always handle errors (even when it seems there are none)

\n\n

An error when reading the response body is not uncommon. The network may drop, the server may close the connection, or the body may be too large. Ignoring the error (_) is evil. Always check err:

\n\n
body, err := io.ReadAll(resp.Body)\nif err != nil {\n    // Log the error, return a fallback, or panic\n    log.Printf("Error reading response body: %v", err)\n    return "", fmt.Errorf("failed to read response: %w", err)\n}
\n\n

3. Limit the response body size

\n\n

Imagine: you request an API, and it returns 10 GB of data. Your io.ReadAll will try to load everything into memory. The server will crash. The client will hang. The user will be angry.

\n\n

Solution: use io.LimitReader. Limit the size to a reasonable limit (e.g., 10 MB):

\n\n
const maxBodySize = 10 * 1024 * 1024 // 10 MB\nlimitedReader := io.LimitReader(resp.Body, maxBodySize)\nbody, err := io.ReadAll(limitedReader)\nif err != nil {\n    // Error handling\n}
\n\n

If the response body exceeds the limit, io.ReadAll will simply read the first 10 MB and finish without an error. If you need strict control over exceeding the limit — read on, we will discuss this in the advanced techniques section.

\n\n

4. Close resp.Body — but correctly

\n\n

defer resp.Body.Close() is the standard. But there is a nuance: if you read the body

Blogs

Book Recommendations