如何使用Golang实现REST API客户端_Golang REST API请求与响应处理

2次阅读

最简路径是复用配置超时和transport的全局http.client,检查statuscode和关闭resp.body,用context控制请求生命周期,按业务域隔离client。

如何使用Golang实现REST API客户端_Golang REST API请求与响应处理

net/http 发起 GET/POST 请求最简路径

go 标准库的 net/http 足够轻量且可靠,不需要引入第三方 HTTP 客户端(比如 resty)也能完成绝大多数 rest api 调用。关键在于别直接用 http.Gethttp.Post ——它们不支持超时、无法复用连接、没法设 Header,一上线就容易出问题。

正确做法是构造一个带配置的 http.Client

client := &http.Client{     Timeout: 10 * time.Second,     Transport: &http.Transport{         MaxIdleConns:        100,         MaxIdleConnsPerHost: 100,         IdleConnTimeout:     30 * time.Second,     }, }
  • Timeout 必设,否则请求卡住会拖垮整个服务
  • Transport 配置决定连接复用能力,高并发下没它,dial tcp: too many open files 很快出现
  • 别在每次请求都 new(http.Client),它本身是线程安全的,全局复用即可

处理 json 响应时如何避免 panic 和空指针

json.Unmarshal 解析响应体前,必须检查 resp.Body 是否为 nil,且 resp.StatusCode 是否在 2xx 范围。很多客户端代码只判 err != nil,但 HTTP 错误码(如 401、500)不会触发 err,只会返回非空 resp + 错误 body。

典型错误写法:json.Unmarshal(resp.Body, &v) —— resp.Bodyio.ReadCloser,不能重复读,且没关会导致连接泄漏。

立即学习go语言免费学习笔记(深入)”;

  • 始终用 defer resp.Body.Close()(在检查 resp 不为 nil 后)
  • 先读取 body, _ := io.ReadAll(resp.Body),再传给 json.Unmarshal(body, &v)
  • 对非 2xx 状态码,建议单独解析错误结构体(如 {"Error":"invalid_Token"}),而不是直接 panic

带认证和动态 Header 的请求怎么组织更可控

Token 类认证(Bearer、API Key)不该硬编码在每个请求里。推荐封装一个带上下文的请求函数,把认证逻辑收口:

func DoRequest(ctx context.Context, method, url string, body io.Reader, headers map[string]string) (*http.Response, error) {     req, err := http.NewRequestWithContext(ctx, method, url, body)     if err != nil {         return nil, err     }     for k, v := range headers {         req.Header.Set(k, v)     }     return client.Do(req) }
  • context.WithTimeout 控制单次请求生命周期,比 Client.Timeout 更灵活(比如某些接口允许 30s,其他只要 2s)
  • headersmap 传入,方便动态加 AuthorizationX-Request-IDContent-Type
  • 如果 Token 从外部获取(如 JWT),不要在函数内调用刷新逻辑——那属于业务层职责,客户端只负责“拿已知 token 发请求”

为什么 http.Client 不该全局变量乱传

很多人把 *http.Client 当成工具类塞进各种 Struct,甚至作为参数层层传递。这会导致两个实际问题:一是测试时无法 mock(标准库 client 没接口抽象);二是不同业务共用同一 Transport,某个接口频繁失败可能拖慢其他请求(比如长连接被异常服务器占满)。

  • 按业务域隔离 client:支付调用用一个,用户服务调用用另一个,各自配独立 Transport
  • 真要 mock 测试,用 http.ServeMux 起个本地 test server,或用 httptest.NewServer,比试图替换 client 更可靠
  • 如果用了依赖注入框架(如 fx),client 应作为 singleton 提供,但需明确标注用途,比如 PaymentHTTPClient

真正难的不是发请求,而是让错误可观察、连接可管理、行为可测试。Header 写错、JSON 字段名大小写不一致、Body 没 close、超时时间设成 0 —— 这些细节在压测或网络抖动时才暴露。

text=ZqhQzanResources