gohttpwikipedia-api

Wikipedia API returns empty body


I'm calling the Wikipedia API in Go using the http package. However, the response from Wikipedia is 200 OK and an empty body.

My code is below:

package main

import (
    "fmt"
    "net/http"
    "net/url"
    "os"
    "strings"
)

const SECRET = "secret.txt"
const BASE = "https://en.wikipedia.org/w/api.php"

func main() {
    secret, err := os.ReadFile(SECRET)
    if err != nil {
        panic(err)
    }

    userAgent := strings.TrimSpace(string(secret))

    u, err := url.Parse(BASE)
    if err != nil {
        panic(err)
    }

    params := url.Values{
        "action":        {"query"},
        "list":          {"categorymembers"},
        "cmtitle":       {"Category:Physics"},
        "cmlimit":       {"10"},
        "format":        {"json"},
        "formatversion": {"2"},
    }
    u.RawQuery = params.Encode()

    req, err := http.NewRequest(http.MethodGet, u.String(), nil)
    if err != nil {
        panic(err)
    }
    req.Header.Set("User-Agent", userAgent)

    fmt.Println(req.URL)

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }

    fmt.Println(resp.StatusCode, resp.ContentLength)
    fmt.Println(resp)

    var body []byte
    _, err = resp.Body.Read(body)
    if err != nil {
        panic(err)
    }

    fmt.Println(string(body))
}

When I use the generated URL in a web browser, it gives me a JSON output as expected. Why is this?


Solution

  • Using var body []byte like this creates slice with a capacity 0. Passing this into Read() means that it will try to fill the capacity-0 slice with bytes. Since the slice has no more capacity, it returns with no error, and with the "empty" slice.

    Replacing it with body, err := io.ReadAll(resp.Body) works, since io.ReadAll() consumes the entire Reader and returns it as a []byte.