Resty:Go 语言中最优雅的 HTTP 客户端库
前言
在 Go 语言生态中,标准库 net/http 虽然功能完备,但使用起来往往需要编写大量重复代码。今天要介绍的 Resty(https://github.com/go-resty/resty),是一个为 Go 语言打造的简单而强大的 HTTP 客户端库,它让 HTTP 请求变得像链式调用一样优雅。
项目简介
Resty 是一个受 Ruby 的 RestClient 启发的 HTTP 客户端库,它的设计目标是简化 HTTP 请求,让开发者用更少的代码完成更多的事情。自发布以来,它已经成为 Go 生态中最受欢迎的 HTTP 客户端之一,拥有超过 9k+ 的 Star。
核心特性
1. 链式调用 API
Resty 最大的特色是支持链式调用,让代码读起来像自然语言:
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetBody(`{"name":"golang"}`).
Post("https://example.com/api")2. 自动 JSON/XML 编解码
无需手动序列化和反序列化:
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
resp, err := client.R().
SetBody(User{Name: "Alice", Age: 25}).
SetResult(&User{}).
Post("https://api.example.com/users")3. 内置重试机制
支持自定义重试策略,无需额外依赖:
client. SetRetryCount(3). SetRetryWaitTime(500 * time.Millisecond). SetRetryMaxWaitTime(3 * time.Second)
4. 请求/响应中间件
可以在请求前后插入自定义逻辑:
client.OnBeforeRequest(func(c *resty.Client, r *resty.Request) error {
// 添加 token
r.SetHeader("Authorization", "Bearer "+token)
return nil
})
client.OnAfterResponse(func(c *resty.Client, r *resty.Response) error {
// 统一处理响应
log.Printf("Status: %d", r.StatusCode())
return nil
})5. 丰富的请求配置
一键支持各种常见需求:
resp, err := client.R().
SetQueryParams(map[string]string{"page": "1"}).
SetPathParam("id", "123").
SetHeader("Accept", "application/json").
SetAuthToken("my-token").
SetBasicAuth("user", "pass").
SetTimeout(5 * time.Second).
SetContext(ctx).
Get("/users/{id}")快速上手
安装
go get -u github.com/go-resty/resty/v2
基础示例
package main
import (
"fmt"
"github.com/go-resty/resty/v2"
)
func main() {
client := resty.New()
resp, err := client.R().
SetQueryParam("q", "golang").
Get("https://api.github.com/search/repositories")
if err != nil {
panic(err)
}
fmt.Println("Status:", resp.Status())
fmt.Println("Body:", resp.String())
}结构体绑定示例
type Repository struct {
Name string `json:"name"`
Stars int `json:"stargazers_count"`
}
resp, err := client.R().
SetQueryParam("q", "resty").
SetResult(&[]Repository{}).
Get("https://api.github.com/search/repositories")
if err == nil {
repos := resp.Result().(*[]Repository)
for _, r := range *repos {
fmt.Printf("%s: %d stars\n", r.Name, r.Stars)
}
}进阶用法
多区块文件上传
Resty 支持文件上传,包括多区块表单:
resp, err := client.R().
SetFileReader("avatar", "user.jpg", fileReader).
SetFormData(map[string]string{"name": "Alice"}).
Post("https://api.example.com/upload")认证支持
内置多种认证方式:
// Basic Auth
client.SetBasicAuth("username", "password")
// Bearer Token
client.SetAuthToken("my-token")
// Digest Auth
client.SetAuthScheme("Bearer")
// 也支持 OAuth2使用客户端共用配置
client := resty.New().
SetBaseURL("https://api.example.com").
SetHeader("Accept", "application/json").
SetTimeout(10 * time.Second).
SetRetryCount(2)
// 所有请求自动继承配置
client.R().Get("/users")
client.R().Get("/posts")与标准库对比
以一次带 JSON 请求和响应的 POST 调用为例:
标准库 net/http:
body, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
var result User
json.Unmarshal(respBody, &result)Resty:
var result User resp, err := resty.New().R(). SetBody(data). SetResult(&result). Post(url)
代码量减少 70% 以上,可读性大幅提升。
性能表现
Resty 在标准库 net/http 之上做了轻量封装,性能损耗极小。得益于其连接池和配置复用机制,在高并发场景下表现优异。同时它对 context 支持完善,可以很方便地做超时和取消控制。
适用场景
微服务间调用:重试、超时、header 传递等需求都很容易满足
第三方 API 集成:JSON 编解码简单直接
爬虫与数据采集:链式调用适合快速开发
SDK 客户端封装:中间件机制适合统一日志、鉴权
小提示
生产环境建议复用
resty.Client实例,而非每次resty.New(),以便共享连接池使用
SetContext做超时控制,比全局超时更灵活结合
OnAfterResponse实现统一的错误处理和日志记录复杂错误处理可以利用
resp.Error()拿到自定义错误结构
总结
Resty 用简洁的链式 API 与强大的内置功能,将 Go 语言的 HTTP 客户端体验提升了一个档次。它不是简单地封装了 net/http,而是从开发者的实际需求出发,把重试、编解码、中间件、上传下载等常用场景抽象为一行配置。如果你还在为繁琐的 HTTP 请求代码烦恼,Resty 值得一试。
项目地址:https://github.com/go-resty/resty
官方文档:https://resty.dev
用 Resty,写 Go HTTP 客户端,从此告别样板代码。



还没有评论,来说两句吧...