一架梯子,一头程序猿,仰望星空!
Go Resty教程 > 内容正文

Go Resty快速入门


Go Resty是一个用于构建RESTful API客户端的Go语言库,使用Go Resty,开发人员可以更快速和高效地构建可靠的RESTful API客户端, 本章介绍怎么快速上手Go Resty。

安装

require github.com/go-resty/resty/v2 v2.7.0

或者

go get github.com/go-resty/resty/v2

Resty例子

下面的示例将帮助您尽可能舒适地使用 resty 库。

// 将 resty 导入到您的代码中,并将其引用为 `resty`。
import "github.com/go-resty/resty/v2"

简单的 GET 请求

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

resp, err := client.R().
    EnableTrace().
    Get("https://httpbin.org/get")

// 探索响应对象
fmt.Println("响应信息:")
fmt.Println("  错误  :", err)
fmt.Println("  状态码:", resp.StatusCode())
fmt.Println("  状态  :", resp.Status())
fmt.Println("  协议  :", resp.Proto())
fmt.Println("  时间  :", resp.Time())
fmt.Println("  接收于:", resp.ReceivedAt())
fmt.Println("  主体  :\n", resp)
fmt.Println()

// 探索跟踪信息
fmt.Println("请求跟踪信息:")
ti := resp.Request.TraceInfo()
fmt.Println("  DNS 查询       :", ti.DNSLookup)
fmt.Println("  连接时间       :", ti.ConnTime)
fmt.Println("  TCP 连接时间   :", ti.TCPConnTime)
fmt.Println("  TLS 握手时间   :", ti.TLSHandshake)
fmt.Println("  服务器响应时间 :", ti.ServerTime)
fmt.Println("  响应时间       :", ti.ResponseTime)
fmt.Println("  总时间         :", ti.TotalTime)
fmt.Println("  是否重用连接   :", ti.IsConnReused)
fmt.Println("  连接是否闲置   :", ti.IsConnWasIdle)
fmt.Println("  连接闲置时间   :", ti.ConnIdleTime)
fmt.Println("  请求尝试次数   :", ti.RequestAttempt)
fmt.Println("  远程地址       :", ti.RemoteAddr.String())

/* 输出
响应信息:
  错误  :
  状态码: 200
  状态  : 200 OK
  协议  : HTTP/2.0
  时间  : 457.034718ms
  接收于: 2020-09-14 15:35:29.784681 -0700 PDT m=+0.458137045
  主体  :
  {
    "args": {},
    "headers": {
      "Accept-Encoding": "gzip",
      "Host": "httpbin.org",
      "User-Agent": "go-resty/2.4.0 (https://github.com/go-resty/resty)",
      "X-Amzn-Trace-Id": "Root=1-5f5ff031-000ff6292204aa6898e4de49"
    },
    "origin": "0.0.0.0",
    "url": "https://httpbin.org/get"
  }

请求跟踪信息:
  DNS 查询       : 4.074657ms
  连接时间       : 381.709936ms
  TCP 连接时间   : 77.428048ms
  TLS 握手时间   : 299.623597ms
  服务器响应时间 : 75.414703ms
  响应时间       : 79.337µs
  总时间         : 457.034718ms
  是否重用连接   : false
  连接是否闲置   : false
  连接闲置时间   : 0s
  请求尝试次数   : 1
  远程地址       : 3.221.81.55:443

复杂点的GET请求

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

// 设置查询参数
resp, err := client.R().
      SetQueryParams(map[string]string{
          "page_no": "1",
          "limit": "20",
          "sort":"name",
          "order": "asc",
          "random":strconv.FormatInt(time.Now().Unix(), 10),
      }).
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/search_result")


// 使用Request.SetQueryString方法的示例
resp, err := client.R().
      SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more").
      SetHeader("Accept", "application/json").
      SetAuthToken("BC594900518B4F7EAC75BD37F019E08FBC594900518B4F7EAC75BD37F019E08F").
      Get("/show_product")


// 如果需要,可以强制指定响应内容类型告诉Resty将JSON响应解析为你的结构体
resp, err := client.R().
      SetResult(result).
      ForceContentType("application/json").
      Get("v2/alpine/manifests/latest")

多种POST请求示例

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

// POST JSON字符串
// 如果已经设置了客户端级别的设置,则无需设置内容类型
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      SetResult(&AuthSuccess{}).    // 或者 SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST []byte字节数组
// 如果已经设置了客户端级别的设置,则无需设置内容类型
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`)).
      SetResult(&AuthSuccess{}).    // 或者 SetResult(AuthSuccess{}).
      Post("https://myapp.com/login")

// POST结构体,默认是JSON内容类型,无需设置
resp, err := client.R().
      SetBody(User{Username: "testuser", Password: "testpass"}).
      SetResult(&AuthSuccess{}).    // 或者 SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // 或者 SetError(AuthError{}).
      Post("https://myapp.com/login")

// POST Map,默认是JSON内容类型,无需设置
resp, err := client.R().
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
      SetResult(&AuthSuccess{}).    // 或者 SetResult(AuthSuccess{}).
      SetError(&AuthError{}).       // 或者 SetError(AuthError{}).
      Post("https://myapp.com/login")

// 以原始字节数组形式进行文件上传。例如:将文件上传到Dropbox
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")

// 注意,我们没有设置内容类型头,因为go-resty会自动检测Content-Type
resp, err := client.R().
      SetBody(fileBytes).
      SetContentLength(true).          // Dropbox需要这个值
      SetAuthToken("").
      SetError(&DropboxError{}).       // 或者 SetError(DropboxError{}).
      Post("https://content.dropboxapi.com/1/files_put/auto/resty/mydocument.pdf") // DropBox也支持PUT方式上传

// 注意:如果没有设置内容类型头,resty会检测请求体的Content-Type
//   * 对于结构体和map数据类型,默认为'application/json'
//   * 然后是普通文本内容类型

PUT请求

您可以像演示 POST 一样使用各种 PUT 方法调用的组合。

// 注意:这是使用PUT方法的一个示例,更多组合请参阅POST

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

// 请求以JSON内容类型发送
// 如果有客户端级别的设置,可以不设置身份验证令牌,错误
resp, err := client.R().
      SetBody(Article{
        Title: "go-resty",
        Content: "这是我的文章内容,哦耶!",
        Author: "Jeevanandam M",
        Tags: []string{"文章", "示例", "resty"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&错误{}).       // 或者 SetError(Error{}).
      Put("https://myapp.com/article/1234")

PATCH请求

您可以像演示 POST 一样使用各种 PATCH 方法调用的组合。

// 注意:这是使用PATCH方法的一个示例,更多组合请参阅POST

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

// 请求以JSON内容类型发送
// 如果有客户端级别的设置,可以不设置身份验证令牌,错误
resp, err := client.R().
      SetBody(Article{
        Tags: []string{"新标签1", "新标签2"},
      }).
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&错误{}).       // 或者 SetError(Error{}).
      Patch("https://myapp.com/articles/1234")

DELETE, HEAD, OPTIONS请求

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

// 删除一篇文章
// 如果有客户端级别的设置,可以不设置身份验证令牌,错误
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&错误{}).       // 或者 SetError(Error{}).
      Delete("https://myapp.com/articles/1234")

// 以JSON字符串作为有效载荷/内容的方式删除多篇文章
// 如果有客户端级别的设置,可以不设置身份验证令牌,错误
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      SetError(&错误{}).       // 或者 SetError(Error{}).
      SetHeader("Content-Type", "application/json").
      SetBody(`{article_ids: [1002, 1006, 1007, 87683, 45432] }`).
      Delete("https://myapp.com/articles")

// 获取资源的头信息
// 如果有客户端级别的设置,可以不设置身份验证令牌
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Head("https://myapp.com/videos/hi-res-video")

// 获取资源的选项信息
// 如果有客户端级别的设置,可以不设置身份验证令牌
resp, err := client.R().
      SetAuthToken("C6A79608-782F-4ED0-A11D-BD82FAD829CD").
      Options("https://myapp.com/servers/nyc-dc-01")

设置JSON和XML序列化/反序列化操作

用户可以将选择的JSON/XML库注册到resty中,或者编写自己的库。默认情况下,resty分别注册标准的 encoding/jsonencoding/xml

// 注册json-iterator的示例
import jsoniter "github.com/json-iterator/go"

json := jsoniter.ConfigCompatibleWithStandardLibrary

client := resty.New().
    SetJSONMarshaler(json.Marshal).
    SetJSONUnmarshaler(json.Unmarshal)

// 类似地,用户可以使用以下方式对XML进行设置 -
client.SetXMLMarshaler(xml.Marshal).
    SetXMLUnmarshaler(xml.Unmarshal)