Go - httpclient 常用操作

简介: Go - httpclient 常用操作

模块介绍

httpclient 是基于 net/http 封装的 Go HTTP 客户端请求包,支持常用的请求方式、常用设置,比如:

  • 支持设置 Mock 信息
  • 支持设置失败时告警
  • 支持设置失败时重试
  • 支持设置项目内部的 Trace
  • 支持设置超时时间、Header 等

请求说明

方法名 描述
httpclient.Get() GET 请求
httpclient.Post() POST 请求
httpclient.PostForm() POST 请求,form 形式
httpclient.PostJSON() POST 请求,json 形式
httpclient.PutForm() PUT 请求,form 形式
httpclient.PutJSON() PUT 请求,json 形式
httpclient.PatchForm() PATCH 请求,form 形式
httpclient.PatchJSON() PATCH 请求,json 形式
httpclient.Delete() DELETE 请求

配置说明

配置项 配置方法
设置 TTL 本次请求最大超时时间 httpclient.WithTTL(ttl time.Duration)
设置 Header 信息 httpclient.WithHeader(key, value string)
设置 Logger 信息 httpclient.WithLogger(logger *zap.Logger)
设置 Trace 信息 httpclient.WithTrace(t trace.T)
设置 Mock 信息 httpclient.WithMock(m Mock)
设置失败时告警 httpclient.WithOnFailedAlarm(alarmTitle string, alarmObject AlarmObject, alarmVerify AlarmVerify)
设置失败时重试 httpclient.WithOnFailedRetry(retryTimes int, retryDelay time.Duration, retryVerify RetryVerify)

设置 TTL

// 设置本次请求最大超时时间为 5s
httpclient.WithTTL(time.Second*5),

设置 Header 信息

可以调用多次进行设置多对 key-value 信息。

// 设置多对 key-value 信息,比如这样:
httpclient.WithHeader("Authorization", "xxxx"),
httpclient.WithHeader("Date", "xxxx"),

设置 Logger 信息

传递的 logger 便于 httpclient 打印日志。

// 使用上下文中的 logger,比如这样:
httpclient.WithLogger(ctx.Logger()),

设置 Trace 信息

传递的 trace 便于记录使用 httpclient 调用第三方接口的链路日志。

// 使用上下文中的 trace,比如这样:
httpclient.WithTrace(ctx.Trace()),

设置 Mock 信息

// Mock 类型
type Mock func() (body []byte)
// 需实现 Mock 方法,比如这样:
func MockDemoPost() (body []byte) {
 res := new(demoPostResponse)
 res.Code = 1
 res.Msg = "ok"
 res.Data.Name = "mock_Name"
 res.Data.Job = "mock_Job"
 body, _ = json.Marshal(res)
 return body
}
// 使用时:
httpclient.WithMock(MockDemoPost),

传递的 Mock 方式便于设置调用第三方接口的 Mock 数据。只要约定了接口文档,即使对方接口未开发时,也不影响数据联调。

设置失败时告警

// alarmTitle 设置失败告警标题 String
// AlarmObject 告警通知对象,可以是邮件、短信或微信
type AlarmObject interface {
 Send(subject, body string) error
}
// 需要去实现 AlarmObject 接口,比如这样:
var _ httpclient.AlarmObject = (*AlarmEmail)(nil)
type AlarmEmail struct{}
func (a *AlarmEmail) Send(subject, body string) error {
 options := &mail.Options{
  MailHost: "smtp.163.com",
  MailPort: 465,
  MailUser: "xx@163.com",
  MailPass: "",
  MailTo:   "",
  Subject:  subject,
  Body:     body,
 }
 return mail.Send(options)
}
// AlarmVerify 定义符合告警的验证规则
type AlarmVerify func(body []byte) (shouldAlarm bool)
// 需要去实现 AlarmVerify 方法,比如这样:
func alarmVerify(body []byte) (shouldalarm bool) {
 if len(body) == 0 {
  return true
 }
 type Response struct {
  Code int `json:"code"`
 }
 resp := new(Response)
 if err := json.Unmarshal(body, resp); err != nil {
  return true
 }
    // 当第三方接口返回的 code 不等于约定的成功值(1)时,就要进行告警
 return resp.Code != 1
}
// 使用时:
httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), alarmVerify),

设置失败时重试

// retryTimes 设置重试次数 Int,默认:3
// retryDelay 设置重试前延迟等待时间 time.Duration,默认:time.Millisecond * 100
// RetryVerify 定义符合重试的验证规则
type RetryVerify func(body []byte) (shouldRetry bool)
// 需要去实现 RetryVerify 方法,比如这样:
func retryVerify(body []byte) (shouldRetry bool) {
 if len(body) == 0 {
  return true
 }
 type Response struct {
  Code int `json:"code"`
 }
 resp := new(Response)
 if err := json.Unmarshal(body, resp); err != nil {
  return true
 }
    // 当第三方接口返回的 code 等于约定值(10010)时,就要进行重试
 return resp.Code = 10010
}
// RetryVerify 也可以为 nil , 当为 nil 时,默认重试规则为 http_code 为如下情况:
// http.StatusRequestTimeout, 408
// http.StatusLocked, 423
// http.StatusTooEarly, 425
// http.StatusTooManyRequests, 429
// http.StatusServiceUnavailable, 503
// http.StatusGatewayTimeout, 504
// 使用时:
httpclient.WithOnFailedRetry(3, time.Second*1, retryVerify),

示例代码

// 以 httpclient.PostForm 为例
api := "http://127.0.0.1:9999/demo/post"
params := url.Values{}
params.Set("name", name)
body, err := httpclient.PostForm(api, params,
 httpclient.WithTTL(time.Second*5),
 httpclient.WithTrace(ctx.Trace()),
 httpclient.WithLogger(ctx.Logger()),
 httpclient.WithHeader("Authorization", "xxxx"),
 httpclient.WithMock(MockDemoPost),
    httpclient.WithOnFailedRetry(3, time.Second*1, retryVerify),
    httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), alarmVerify),                             
)
if err != nil {
    return nil, err
}
res = new(demoPostResponse)
err = json.Unmarshal(body, res)
if err != nil {
    return nil, errors.Wrap(err, "DemoPost json unmarshal error")
}
if res.Code != 1 {
    return nil, errors.New(fmt.Sprintf("code err: %d-%s", res.Code, res.Msg))
}
return res, nil


以上代码在 go-gin-api 项目中,地址:https://github.com/xinliangnote/go-gin-api

目录
相关文章
|
Unix Go
一文了解 Go time 包的时间常用操作
Go time 包的使用。介绍如何获取当前时间、获取具体时间单位的值、时间格式化和字符串与时间类型相互转换等操作。掌握了这些函数和方法的使用,应对开发中时间操作的场景不成问题。
317 1
一文了解 Go time 包的时间常用操作
|
缓存 安全 Go
Go 开发常用操作技巧--模块管理
Go 依赖管理经历了 3 个阶段,GOPATH、Go Vendor、Go Module。
135 0
Go 开发常用操作技巧--模块管理
Go 开发常用操作技巧--字符串
Go 语言字符串的字节使用的是UTF-8编码,是一种变长的编码方式。使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
244 0
Go 开发常用操作技巧--字符串
|
Go 索引
Go 开发常用操作技巧--数组
在go语言中,数组的长度是不可变的,这就导致数组在实际使用中不是很灵活,为此,设计了动态数组--Slice(切片)。
182 0
Go 开发常用操作技巧--数组
|
JSON Go 数据格式
Go 开发常用操作技巧--map
map 是一种特殊的数据类型,它是一种元素对的无序集合,元素对为 键(key)值(value) 形式。我们可以通过 key 来快速找到与之对应的 value。
144 0
Go 开发常用操作技巧--map
|
JSON Go 数据格式
Go 开发常用操作技巧--结构体
结构体是由一系列相同或不相同类型数据组成的数据集合
85 0
Go 开发常用操作技巧--结构体
Go 开发常用操作技巧--接口
接口(interface)是对其他类型行为的抽象。接口是一种约束形式,其中只包括成员函数定义,不包含成员函数实现
126 0
Go 开发常用操作技巧--接口
|
存储 安全 Go
Go 开发常用操作技巧--channel
在 Go 语言中,提倡使用通信来共享内存,而不是通过共享内存来通信,这里的通信就是通过 channel 发送接收消息的方式进行数据传递,而不是通过修改同一个变量。
182 0
Go 开发常用操作技巧--channel
|
应用服务中间件 Go nginx
排查go开发的HttpClient读取Body超时
记一次go httpclient [读取响应Body超时]的排查过程。 今年度解锁的第一个技能
排查go开发的HttpClient读取Body超时
|
22天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
36 7