go网络请求包resty-创新互联

简介

resty是 Go 语言的一个 HTTP client 库。resty功能十分强大,特性丰富,并提供了简单易用的 API。
详情请到 官方文档地址https://github.com/go-resty/resty

成都创新互联公司成立10多年来,这条路我们正越走越好,积累了技术与客户资源,形成了良好的口碑。为客户提供成都网站设计、成都网站建设、网站策划、网页设计、空间域名、网络营销、VI设计、网站改版、漏洞修补等服务。网站是否美观、功能强大、用户体验好、性价比高、打开快等等,这些对于网站建设都非常重要,成都创新互联公司通过对建站技术性的掌握、对创意设计的研究为客户提供一站式互联网解决方案,携手广大客户,共同发展进步。
  • 安装
// step1: 打开 go.mod文件 ==================================
// 加入一下 引用
require github.com/go-resty/resty/v2 v2.7.0

// step2: 打开main.go文件 ==================================
package main

import (
	"fmt"
    // 加入 指定版本的 引用 
	"github.com/go-resty/resty/v2"
)

func main() {client := resty.New()
	resp, err := client.R().Get("https://httpbin.org/get")
	fmt.Println("  Status     :", resp.Status())
}

// step3: 下载包 ==================================
go mod tidy
一般使用 客户端

调用一个resty.New() 创建一个client对象(客户端)

  • 开启 debug 模式
    每次请求可以 查看 请求报文 和 响应报文 的详细信息。
client := resty.New()

// Enable debug mode
client.SetDebug(true)
  • 禁用 https 证书检查
client.SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true })
  • 请求超时设置
client.SetTimeout(1 * time.Minute)
  • URL公共部分抽离
client := resty.New()
client.SetBaseURL("https://whero.com")
resp, err := client.R().Get("/s/user")
请求方法 Get

调用client对象的R() 方法创建一个请求对象;

  • Query
// Create a Resty Client
client := resty.New()

resp, err := client.R().
      SetQueryParams(map[string]string{  "age": "13",
          "name": "tom",
      }).Get("/search_result")
  • Params
client.R().
  SetPathParams(map[string]string{"age": "12",
    "name": "tom",
  }).
  Get("/users/{age}/{name}")
  • 请求体
client := resty.New()

// 让get请求携带请求体参数需要额外配置
client.SetAllowGetMethodPayload(true)

resp, err := client.R().
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      Get("/search_result")
Post
  • json
// Create a Resty Client
client := resty.New()

// POST JSON string
resp, err := client.R().
      SetHeader("Content-Type", "application/json").
      // 请求体   
      SetBody(`{"username":"testuser", "password":"testpass"}`).
      Post("https:")

// POST []byte array
      SetBody([]byte(`{"username":"testuser", "password":"testpass"}`))

// POST Struct, default is JSON content type. No need to set one
      SetBody(User{Username: "testuser", Password: "testpass"}).

// POST Map, default is JSON content type. No need to set one
      SetBody(map[string]interface{}{"username": "testuser", "password": "testpass"}).
  • form-data
resp, err := client.R().
	SetFormData(map[string]string{"access_token": "BC594900-518B-4F7E-AC75-BD37F019E08F",
	}).
	Post("")
  • x-www-form-urlencoded
Put
// Create a Resty Client
client := resty.New()

// Request goes as JSON content type
// No need to set auth token, error, if you have client level settings
resp, err := client.R().
      SetBody(Article{Title: "go-resty",
      }).
      Put("")
Delete
resp, err := client.R().
      Delete("")
响应体
  • 响应数据
resp, _ := client.R().Get("https://baidu.com")


  fmt.Println("Status Code:", resp.StatusCode()) // 状态码,如 200;
  fmt.Println("Status:", resp.Status()) // 状态码和状态信息,如 200 OK;
  fmt.Println("Proto:", resp.Proto()) // 协议,如 HTTP/1.1;
  fmt.Println("Time:", resp.Time()) // 从发送请求到收到响应的时间;
  fmt.Println("Received At:", resp.ReceivedAt()) // 接收到响应的时刻;
  fmt.Println("Size:", resp.Size()) // 响应大小;
  
  fmt.Println("Headers:", resp.Header()) // 响应首部信息,以http.Header类型返回,即map[string][]string;
  for key, value := range resp.Header() {fmt.Println(key, "=", value)
  }
  fmt.Println("Cookies:", resp.Cookies()) // 服务器通过Set-Cookie首部设置的 cookie 信息。
  for i, cookie := range resp.Cookies() {fmt.Printf("cookie%d: name:%s value:%s\n", i, cookie.Name, cookie.Value)
  }
  • 自动 Unmarshal
    返回结构化的数据,如 JSON/XML 格式等。resty可以自动将响应数据 Unmarshal 到对应的结构体对象中。
type Man struct {Name  string
  Age   int64
}

func main() {client := resty.New()
  tom := &Man{}
  client.R().SetResult(tom). // 通过 SetResult 方法 将数据反射到 结构体 上。
    Get("")
}

一般请求下,resty会根据响应中的Content-Type来推断数据格式。但是有时候响应中无Content-Type首部或与内容格式不一致,
我们可以通过调用请求对象的 ForceContentType()强制让resty按照特定的格式来 解析响应:

client.R().
  SetResult(tom).
  ForceContentType("application/json").
  Get("")
请求头
  • 设置一般首部
client.R().
	SetHeader("Content-Type", "application/json").
	SetHeader("aaa", "bbb").
  	Get("")


client.SetHeaders(map[string]string{"Content-Type": "application/json",
        "aaa": "bbb",
      })
  • Content-Length首部,resty自动计算
client.R().
  SetBody(User{Name:"dj"}).
  SetContentLength(true).
  Get("")
上下文件 上传文件
  • 通过 io.Reader
file1, _ := ioutil.ReadFile("./static/aaa.png")
file2, _ := ioutil.ReadFile("./static/bbb.png")

client := resty.New()

client.R().
  SetFileReader("file_one", file1).
  SetFileReader("file_two", file2).
  SetFormData(map[string]string{"name": "tom",
    "age": "11",
  })
  Post("")
  • 通过 文件路径
client := resty.New()

client.R().
  SetFile("file_one", "./static/aaa.png").
  SetFile("file_two", "./static/bbb.png").
  SetFiles(map[string]string{"file1": "./static/aaa.png",
    "file2": "./static/bbb.png",
  }).
  SetFormData(map[string]string{"name": "tom",
    "age": "11",
  })
  Post("")
下载文件
client := resty.New()
// 如果该目录 不存在 则会 自动创建
client.SetOutDirectory("/home/hero")

// 使用相对路径, 相对SetOutDirectory 设置的路径
client.R().
  SetOutput("static/aaa.png").
  Get("")

// 也可以使用绝对路径
client.R().
  SetOutput("/home/hero/static/aaa.png").
  Get("")
高级应用 中间件

Resty 提供了和Gin类似的中间件特性。 OnBeforeRequest 和 OnAfterResponse 回调方法,可以在请求之前和响应之后加入自定义逻辑。参数包含了 resty.Client 和当前请求的 resty.Request 对象。成功时返回 nil ,失败时返回 error 对象。

client := resty.New()

client.OnBeforeRequest(func(c *resty.Client, req *resty.Request) error {return nil
})

client.OnAfterResponse(func(c *resty.Client, resp *resty.Response) error {return nil
})
请求重试

由于网络抖动带来的接口稳定性的问题 Resty 提供了重试功能来解决。SetRetryCount设置重试次数,SetRetryWaitTimeSetRetryMaxWaitTime设置等待时间。SetRetryAfter是一个重试后的回调方法。除此之外还可以调用AddRetryCondition设置重试的条件。

client := resty.New()

client.
    SetRetryCount(3).
    SetRetryWaitTime(5 * time.Second).
    SetRetryMaxWaitTime(20 * time.Second).
    SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {return 0, errors.New("quota exceeded")
    })

client.AddRetryCondition(
    func(r *resty.Response) (bool, error) {return r.StatusCode() == http.StatusTooManyRequests
    },
)
代理

Resty 提供了 SetProxy 方法为请求添加代理,还可以调用 RemoveProxy 移除代理。

client := resty.New()
client.SetProxy("http://proxyserver:1234")
client.RemoveProxy()
debug模式

Go1.7 引入了HTTP trace,可以在HTTP客户端请求过程中收集一些更细粒度的信息,httptrace包提供了HTTP trace的支持,收集的信息可用于调试延迟问题,服务监控,编写自适应系统等。httptrace包提供了许多钩子,在HTTP往返期间收集各种事件的信息,包括连接的创建、复用、DNS解析查询、写入请求和读取响应。

resty提供的一个辅助功能:trace, 就是基于 httptrace包。我们在请求对象上调用EnableTrace()方法启用 trace。启用 trace 可以记录请求的每一步的耗时和其他信息。

resp, err :=client.R().EnableTrace().Get("https://baidu.com")

ti := resp.Request.TraceInfo()

fmt.Println("DNSLookup:", ti.DNSLookup) // DNS 查询时间,如果提供的是一个域名而非 IP,就需要向 DNS 系统查询对应 IP 才能进行后续操作;
fmt.Println("ConnTime:", ti.ConnTime) // 获取一个连接的耗时,可能从连接池获取,也可能新建;
fmt.Println("TCPConnTime:", ti.TCPConnTime) // TCP 连接耗时,从 DNS 查询结束到 TCP 连接建立;
fmt.Println("TLSHandshake:", ti.TLSHandshake) // TLS 握手耗时;
fmt.Println("ServerTime:", ti.ServerTime) // 服务器处理耗时,计算从连接建立到客户端收到第一个字节的时间间隔;
fmt.Println("ResponseTime:", ti.ResponseTime) // 响应耗时,从接收到第一个响应字节,到接收到完整响应之间的时间间隔;
fmt.Println("TotalTime:", ti.TotalTime) // 整个流程的耗时;
fmt.Println("IsConnReused:", ti.IsConnReused) // TCP 连接是否复用了;
fmt.Println("IsConnWasIdle:", ti.IsConnWasIdle) // 连接是否是从空闲的连接池获取的;
fmt.Println("ConnIdleTime:", ti.ConnIdleTime) // 连接空闲时间;
fmt.Println("RequestAttempt:", ti.RequestAttempt) // 请求执行流程中的请求次数,包括重试次数;
fmt.Println("RemoteAddr:", ti.RemoteAddr.String()) // 远程的服务地址,IP:PORT格式。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章名称:go网络请求包resty-创新互联
新闻来源:http://scyanting.com/article/gdhie.html