Resty不是必须品,仅在高频HTTP调用时省力;应全局复用client避免新建导致DNS/TLS/连接池失效;SetBaseURL替代已弃用的SetHostURL且须以/结尾;JSON自动编解码需显式SetBody或SetResult;重试需手动SetRetryCondition定义条件,仅设RetryCount无效。

resty 不是语法糖,也不是必须品;它只在你反复写 http.NewRequest + client.Do + 手动读 body + 错误判断时才真正省力。如果你的项目里 HTTP 调用不超过 3 处,直接用标准库更轻、更可控。
为什么不用 resty.New() 每次都新建 client?
每次调用 resty.New() 都会创建全新 transport、连接池和 cookie jar,导致:
- DNS 缓存失效(每次 new 都重新解析域名)
- TLS 会话无法复用(握手开销翻倍)
- 连接池被绕过(大量 TIME_WAIT 或“too many open files”错误)
正确做法是在 main() 或 service 初始化阶段只调用一次:client := resty.New(),然后注入到各 handler 或 service 实例中复用。
SetHostURL 和 SetBaseURL 有什么区别?
SetHostURL 是 v2 的旧名(已 deprecated),实际应统一用 SetBaseURL。它决定所有相对路径请求的根地址,比如:
client := resty.New().SetBaseURL("https://api.example.com/v1")
resp, _ := client.R().Get("/users") // 实际请求 https://api.example.com/v1/users
注意:SetBaseURL 必须以 / 结尾,否则路径拼接会出错;如果漏了结尾斜杠,/users 会变成 https://api.example.com/v1users —— 这类错误不报 panic,但返回 404,极难排查。
立即学习“go语言免费学习笔记(深入)”;
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
怎么让 resty 自动处理 JSON 请求/响应?
resty 默认对 application/json 类型自动序列化/反序列化,但前提是显式设置或触发:
- 发请求时用
.SetBody(map[string]any{...})或.SetBody(struct{...}),它会自动设Content-Type: application/json - 收响应时用
.SetResult(&v)或.SetError(&e),它会按Content-Type头自动 decode - 别依赖
.Post(url)直接传字符串 body —— 它不会自动加 header,也不会 JSON encode
常见坑:传 string 类型的 JSON 字符串(如 "{\"name\":\"x\"}")却不设 Content-Type,服务端可能当 text/plain 解析。
重试逻辑必须自己定义条件,不能只靠 SetRetryCount
SetRetryCount(3) 只控制重试次数,不决定“什么情况下重试”。默认情况下,哪怕返回 400 或 500,它也不重试 —— 因为 resty 认为这些是业务错误,不该盲目重试。
要对网络超时、502/503/504、以及部分连接异常重试,得配 SetRetryCondition:
client.SetRetryCondition(func(r *resty.Response, err error) bool {
return err != nil || r.StatusCode() == 502 || r.StatusCode() == 503 || r.StatusCode() == 504
})
注意:err != nil 包含了 DNS 解析失败、连接拒绝、TLS 握手超时等底层错误;但 r.StatusCode() 在 err != nil 时是无效值(r 为 nil),所以判断顺序不能颠倒。

















