You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go服务无法从远程REST API获取全部JSON数据求助

搞定Go客户端拿不到远程API完整JSON数据的问题

嘿,我看了你的代码,结合GitHub API的特性,大概率是这几个坑导致你拿不到全部数据,咱们一个个来解决:

1. 必须处理GitHub API的分页机制!

GitHub的搜索类API默认只返回30条结果,哪怕响应里的total_count显示有几百条,默认请求也只会给你第一页的30条。你得手动循环请求所有分页才能拿到完整数据:

// 示例:遍历所有分页获取完整数据
var allItems []Item
page := 1
perPage := 100 // GitHub允许的最大每页条数,能减少请求次数
baseURL := url // 你的原始API URL

for {
    // 拼接分页参数
    reqURL := fmt.Sprintf("%s?page=%d&per_page=%d", baseURL, page, perPage)
    res, err := netClient.Get(reqURL)
    if err != nil {
        log.Fatalf("请求分页%d失败: %v", page, err)
    }
    // 千万别忘了关闭响应体,否则会造成连接泄漏!
    defer res.Body.Close()

    var pageData JSONData
    if err := json.NewDecoder(res.Body).Decode(&pageData); err != nil {
        log.Fatalf("解码分页%d数据失败: %v", page, err)
    }

    // 把当前页的条目合并到总列表里
    allItems = append(allItems, pageData.Items...)

    // 判断是否到最后一页:如果返回的条目数小于perPage,说明没有更多数据了
    if len(pageData.Items) < perPage {
        break
    }
    page++
}

// 组装完整的结果
fullData := JSONData{
    Count:     len(allItems), // 或者直接用pageData.Count(也就是接口返回的total_count)
    Username:  user,
    Items:     allItems,
}
fmt.Println(fullData)

2. 漏掉了关键的defer res.Body.Close()

你的代码里没有关闭响应体,这会导致HTTP连接泄漏,时间长了会耗尽连接池,甚至影响后续请求的响应读取。拿到响应后第一时间加上这行:

res, getErr := netClient.Get(url)
if getErr != nil {
    log.Fatal(getErr)
}
defer res.Body.Close() // 这行必须加!

3. 超时设置的小矛盾

你给net.Dialer设了50秒超时,但http.Client的Timeout是40秒——这个Client的超时是整个请求生命周期的总超时(包括连接、发送请求、读取响应),所以它会覆盖Dialer的超时。如果你的API响应比较慢,40秒可能不够,建议调大一点:

var netClient = &http.Client{
    Timeout:   time.Second * 60, // 延长总超时到60秒
    Transport: netTransport,
}

另外,还可以给Transport加个ResponseHeaderTimeout,确保读取响应头的时间足够:

var netTransport = &http.Transport{
    Dial: (&net.Dialer{
        Timeout: 50 * time.Second,
    }).Dial,
    TLSHandshakeTimeout:   50 * time.Second,
    ResponseHeaderTimeout: 50 * time.Second, // 新增:等待响应头的超时时间
}

4. 调试小技巧:先看原始响应

如果还是搞不定,先把API返回的原始JSON打印出来,看看是API没给全,还是解码出了问题:

res, getErr := netClient.Get(url)
if getErr != nil {
    log.Fatal(getErr)
}
defer res.Body.Close()

// 读取完整的响应体
bodyBytes, err := io.ReadAll(res.Body)
if err != nil {
    log.Fatal(err)
}
// 打印原始JSON,确认返回内容是否完整
fmt.Println("原始响应内容:", string(bodyBytes))

// 再进行解码操作
var data JSONData
if err := json.Unmarshal(bodyBytes, &data); err != nil {
    log.Fatal(err)
}

这样你就能清楚看到,是API本身只返回了部分数据,还是解码过程中出了问题。


内容的提问来源于stack exchange,提问作者Daniel Oluojomu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 09:06:06