别着急,坐和放宽
使用社交账号登录
resty 包
net/http 更简洁的 APIresty 是一个简单易用的 HTTP 和 REST 客户端库,灵感来自 Ruby 的 rest-client。
go get github.com/go-resty/resty/v2
import "github.com/go-resty/resty/v2"
// 创建客户端
func basicUsage() {
client := resty.New()
// GET 请求
resp, err := client.R().
Get("https://api.example.com/users")
if err != nil {
log.Fatal(err)
}
fmt.Println("状态码:", resp.StatusCode())
fmt.Println("响应体:", string(resp.Body()))
}
// POST 请求
func postExample() {
client := resty.New()
type CreateUserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
type CreateUserResponse struct {
ID int `json:"id"`
Name string `json:"name"`
}
var result CreateUserResponse
resp, err := client.R().
SetHeader("Content-Type", "application/json").
SetBody(CreateUserRequest{
Name: "Alice",
Email: "[email protected]",
}).
SetResult(&result). // 自动解析响应
Post("https://api.example.com/users")
if err != nil {
log.Fatal(err)
}
fmt.Println("创建的用户 ID:", result.ID)
}
func withInterceptors() {
client := resty.New()
// 请求拦截器
client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
// 添加认证
req.SetHeader("Authorization", "Bearer "+getToken())
// 记录日志
log.Printf("发送请求: %s %s", req.Method, req.URL)
return nil
})
// 响应拦截器
client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {
// 记录响应
log.Printf("收到响应: %d, 耗时: %v",
resp.StatusCode(), resp.Time())
return nil
})
// 错误处理
client.OnError(func(req *resty.Request, err error) {
if v, ok := err.(*resty.ResponseError); ok {
log.Printf("错误响应: %d", v.Response.StatusCode())
}
})
resp, _ := client.R().Get("https://api.example.com/users")
}
func withRetry() {
client := resty.New()
// 设置重试
client.
SetRetryCount(3). // 重试 3 次
SetRetryWaitTime(5 * time.Second). // 等待 5 秒
SetRetryMaxWaitTime(20 * time.Second). // 最多等待 20 秒
AddRetryCondition(
func(r *resty.Response, err error) bool {
// 5xx 错误时重试
return r.StatusCode() >= 500
},
)
resp, err := client.R().Get("https://api.example.com/data")
}
func withTimeout() {
client := resty.New()
// 全局超时
client.SetTimeout(10 * time.Second)
// 单个请求超时
resp, err := client.R().
SetContext(context.Background()).
Get("https://api.example.com/users")
// 使用可取消的 context
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
resp, err = client.R().
SetContext(ctx).
Get("https://api.example.com/slow-endpoint")
}
// 封装 API 客户端
type APIClient struct {
client *resty.Client
baseURL string
token string
}
func NewAPIClient(baseURL, token string) *APIClient {
client := resty.New()
// 配置客户端
client.
SetBaseURL(baseURL).
SetTimeout(30 * time.Second).
SetRetryCount(3).
SetHeader("Content-Type", "application/json")
// 添加认证拦截器
client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
if token != "" {
req.SetHeader("Authorization", "Bearer "+token)
}
return nil
})
return &APIClient{
client: client,
baseURL: baseURL,
token: token,
}
}
// 获取用户列表
func (ac *APIClient) GetUsers() ([]User, error) {
var users []User
resp, err := ac.client.R().
SetResult(&users).
Get("/users")
if err != nil {
return nil, err
}
if resp.IsError() {
return nil, fmt.Errorf("API 错误: %d", resp.StatusCode())
}
return users, nil
}
// 创建用户
func (ac *APIClient) CreateUser(name, email string) (*User, error) {
var user User
resp, err := ac.client.R().
SetBody(map[string]string{
"name": name,
"email": email,
}).
SetResult(&user).
Post("/users")
if err != nil {
return nil, err
}
if resp.IsError() {
return nil, fmt.Errorf("创建失败: %d", resp.StatusCode())
}
return &user, nil
}
// 使用
func main() {
client := NewAPIClient("https://api.example.com", "your-token")
users, err := client.GetUsers()
if err != nil {
log.Fatal(err)
}
fmt.Printf("获取到 %d 个用户\n", len(users))
}