当前位置: 首页 > news >正文

go 网络请求包 resty

简介

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

  • 安装
// 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格式。

相关文章:

  • 网站里面的超链接怎么做/百度收录怎么弄
  • 聊城做网站lcbywl/搜易网服务内容
  • 临沂在线上网站建设/域名注册需要什么条件
  • 做英文网站的公司/seo营销名词解释
  • 南平网站开发/东莞seo优化公司
  • 做网站哪家便宜/知乎关键词优化软件
  • 算法编程(美团)
  • 一次Navicat Premium 15(绿色) 命令页面的测试
  • 模糊图像检测(c++)
  • 合宙ESP32S3 CameraWebServe 测试demo
  • 带模糊加工时间的柔性作业车间调度理论和GA复现(python)
  • 【Web前端学习笔记】第二章 CSS常见使用方法
  • 网络文件服务器:FileVista 8.9.3 Crack
  • Prometheus-Exporter详解
  • cmake的使用
  • 操作系统蓝屏无法启动修复后oracle无法使用问题
  • HummerRisk V0.9.0:增加RBAC 拓扑图,云检测、漏洞、主机等模块增加规则
  • springcloud--xxl-job