243

I'd like to parse the response of a web request, but I'm getting trouble accessing it as string.

func main() {
    resp, err := http.Get("http://google.hu/")
    if err != nil {
        // handle error
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)

    ioutil.WriteFile("dump", body, 0600)

    for i:= 0; i < len(body); i++ {
        fmt.Println( body[i] ) // This logs uint8 and prints numbers
    }

    fmt.Println( reflect.TypeOf(body) )
    fmt.Println("done")
}

How can I access the response as string? ioutil.WriteFile writes correctly the response to a file.

I've already checked the package reference but it's not really helpful.

5 Answers 5

401

bs := string(body) should be enough to give you a string.

From there, you can use it as a regular string.

A bit as in this thread
(updated after Go 1.16 -- Q1 2021 -- ioutil deprecation: ioutil.ReadAll() => io.ReadAll()):

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := io.ReadAll(resp.Body)
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

See also GoByExample.

As commented below (and in zzn's answer), this is a conversion (see spec).
See "How expensive is []byte(string)?" (reverse problem, but the same conclusion apply) where zzzz mentioned:

Some conversions are the same as a cast, like uint(myIntvar), which just reinterprets the bits in place.

Sonia adds:

Making a string out of a byte slice, definitely involves allocating the string on the heap. The immutability property forces this.
Sometimes you can optimize by doing as much work as possible with []byte and then creating a string at the end. The bytes.Buffer type is often useful.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks. Do you have any suggestion how could I have figured it out on my own? How does string() do that? Why can't I see it with reflect.TypeOf?
@TiborSzasz It is a simple conversion: see blog.golang.org/slices#TOC_12.
A small improvement to your code would be to use http.StatusOK instead of the raw 200 value!
I've been doing this and finding that my request bodies always have a newline char at the end. Is this normal for a request body or is that cauased by ioutil.ReadAll()??
55

The method you're using to read the http body response returns a byte slice:

func ReadAll(r io.Reader) ([]byte, error)

official documentation

You can convert []byte to a string by using

body, err := io.ReadAll(resp.Body)
bodyString := string(body)

Comments

19

Go 1.16+ update (February 2021)

Deprecation of io/ioutil

code should be

var client http.Client
resp, err := client.Get(url)
if err != nil {
    log.Fatal(err)
}
defer resp.Body.Close()

if resp.StatusCode == http.StatusOK {
    bodyBytes, err := io.ReadAll(resp.Body)
    // if u want to read the body many time
    // u need to restore 
    // reader := io.NopCloser(bytes.NewReader(bodyBytes))
    if err != nil {
        log.Fatal(err)
    }
    bodyString := string(bodyBytes)
    log.Info(bodyString)
}

reference

  1. https://golang.org/doc/go1.16#ioutil
  2. https://stackoverflow.com/a/52076748/2876087

Comments

1

string(byteslice) will convert byte slice to string, just know that it's not only simply type conversion, but also memory copy.

Comments

0

let me explain it with an example

func GetAllTasks() {
    tasks := make(chan string)
    for i := 1; i <= 100; i++ {
        go GetTask(i, tasks)
    }

    for i := 1; i <= 100; i++ {
        print(<-tasks)
    }
}

func GetTask(id int, tasks chan<- string) {
    res, err := http.Get("https://jsonplaceholder.typicode.com/todos/" + strconv.Itoa(id))
    if err != nil {
        panic(err)
    }
    body, err := io.ReadAll(res.Body)
    if err != nil {
        panic(err)
    }
    tasks <- string(body)
}

func main() {
    GetAllTasks()
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.