httpclient 是基於 net/http
封裝的 Go HTTP 客戶端請求包,支持經常使用的請求方式、經常使用設置,好比:git
方法名 | 描述 |
---|---|
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) |
// 設置本次請求最大超時時間爲 5s httpclient.WithTTL(time.Second*5),
能夠調用屢次進行設置多對 key-value 信息。github
// 設置多對 key-value 信息,好比這樣: httpclient.WithHeader("Authorization", "xxxx"), httpclient.WithHeader("Date", "xxxx"),
傳遞的 logger 便於 httpclient 打印日誌。json
// 使用上下文中的 logger,好比這樣: httpclient.WithLogger(ctx.Logger()),
傳遞的 trace 便於記錄使用 httpclient 調用第三方接口的鏈路日誌。api
// 使用上下文中的 trace,好比這樣: httpclient.WithTrace(ctx.Trace()),
// 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-apipost