乐趣区

关于httpclient:Go-httpclient-常用操作

模块介绍

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…

退出移动版