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