模块介绍
httpclient 是基于 net/http
封装的 Go HTTP 客户端申请包,反对罕用的申请形式、罕用设置,比方:
- 反对设置 Mock 信息
- 反对设置失败时告警
- 反对设置失败时重试
- 反对设置我的项目外部的 Trace
- 反对设置超时工夫、Header 等
申请阐明
办法名 | 形容 |
---|---|
httpclient.Get() | GET 申请 |
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/xinliangno…