在GoFrame中使用go-resty请求第三方HTTP API

450 阅读3分钟

在现代Web开发中,经常需要在自己的应用中请求和集成第三方API。在Go语言生态中,有许多优秀的HTTP客户端库可供选择。其中,go-resty以其简洁的API设计和强大的功能成为许多Gopher的首选。本文将介绍如何在GoFrame框架中使用go-resty库发送请求到第三方HTTP API。

安装

首先,确保你已经安装了Go语言环境。然后使用以下命令安装gf命令行工具和go-resty库:

go install github.com/gogf/gf/v2/cmd/gf@latest
go get github.com/go-resty/resty/v2

基本使用

导入必要的包:

import (
  "github.com/go-resty/resty/v2"
  "github.com/gogf/gf/v2/frame/g"
)

发送GET请求

使用resty.R()创建一个请求,然后使用Get()方法发送GET请求:

// 创建Resty客户端
client := resty.New()

resp, err := client.R().
    SetQueryParams(map[string]string{
        "page": "1",
        "size": "20",
    }).
    Get("https://api.example.com/users")

// 错误处理  
if err != nil {
  g.Log().Errorf(ctx, "Request Error: %v", err)
  return
}

// 访问响应数据
data := resp.Result()

发送POST请求

发送POST请求时,可以使用SetBody()设置请求体:

resp, err := client.R().
    SetHeader("Content-Type", "application/json").
    SetBody(`{"username":"testuser", "password":"123456"}`).
    Post("https://api.example.com/login")

请求和响应日志

在开发和调试阶段,查看详细的请求和响应日志对排查问题很有帮助。可以使用SetDebug(true)开启请求日志:

client.SetDebug(true)

高级特性

请求重试

go-resty支持请求重试。你可以指定重试条件、次数和延迟:

client.
    SetRetryCount(3).
    SetRetryWaitTime(5 * time.Second).
    SetRetryMaxWaitTime(20 * time.Second).
    AddRetryCondition(
        func(r *resty.Response, err error) bool {
            return r.StatusCode() == http.StatusTooManyRequests
        },
    )

以上代码设置了最多重试3次,重试延迟为5秒,最大延迟为20秒。同时指定了如果响应状态码为429 Too Many Requests时才进行重试。

中间件

go-resty支持使用中间件来定制请求和响应处理流程。例如,你可以添加一个请求中间件来为每个请求自动添加认证Header:

client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {
    req.SetHeader("Authorization", "Bearer "+accessToken)
    return nil  
})

性能调优

可以使用SetTimeout()设置请求超时时间,避免请求一直阻塞。SetTransport()可以设置自定义的http.RoundTripper接口实现,实现连接池等特性。

超时处理

  1. 设置请求超时时间 可以使用resty.ClientSetTimeout()方法为客户端设置全局的请求超时时间:
client := resty.New()
client.SetTimeout(5 * time.Second)

这样,通过该客户端发送的所有请求,如果超过5秒没有响应,就会返回超时错误。

  1. 为单个请求设置超时 如果只想为某个请求单独设置超时,可以使用resty.RequestSetTimeout()方法:
resp, err := client.R().
    SetTimeout(3 * time.Second).
    Get("https://api.example.com/users")
  1. 检查错误类型 发送请求后,需要检查返回的错误是否为超时错误。可以使用errors.Is()函数判断错误是否为context.DeadlineExceeded类型:
resp, err := client.R().Get("https://api.example.com/users")
if err != nil {
    if errors.Is(err, context.DeadlineExceeded) {
        g.Log().Errorf(ctx, "Request timeout: %v", err)
        // 处理超时错误,例如返回错误响应给客户端
    } else {
        g.Log().Errorf(ctx, "Request error: %v", err) 
        // 处理其他类型的错误
    }
    return
}
  1. 使用Context控制超时 如果你的项目已经使用context.Context来控制请求的生命周期,也可以直接将Context传递给go-resty的请求方法:
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()

resp, err := client.R().
    SetContext(ctx).
    Get("https://api.example.com/users")

这样,当Context超时或取消时,请求也会立即返回超时错误。

总结

本文主要介绍了如何在GoFrame中使用go-resty库发送HTTP请求,涵盖了基本的GET、POST请求方法,以及请求日志、重试、中间件等高级特性。在实际项目中,你还可以利用go-resty的其他特性,例如multipart表单、文件上传、JSON/XML响应解析等,它们都有简洁一致的API。结合GoFrame强大的Web开发特性,go-resty无疑是请求第三方API的绝佳搭档。