模块介绍

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

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

设置 Header 信息

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

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

设置 Logger 信息

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

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

设置 Trace 信息

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

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

设置 Mock 信息

  1. // Mock 类型
  2. type Mock func() (body []byte)
  3. // 需实现 Mock 方法,比如这样:
  4. func MockDemoPost() (body []byte) {
  5. res := new(demoPostResponse)
  6. res.Code = 1
  7. res.Msg = "ok"
  8. res.Data.Name = "mock_Name"
  9. res.Data.Job = "mock_Job"
  10. body, _ = json.Marshal(res)
  11. return body
  12. }
  13. // 使用时:
  14. httpclient.WithMock(MockDemoPost),

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

设置失败时告警

  1. // alarmTitle 设置失败告警标题 String
  2. // AlarmObject 告警通知对象,可以是邮件、短信或微信
  3. type AlarmObject interface {
  4. Send(subject, body string) error
  5. }
  6. // 需要去实现 AlarmObject 接口,比如这样:
  7. var _ httpclient.AlarmObject = (*AlarmEmail)(nil)
  8. type AlarmEmail struct{}
  9. func (a *AlarmEmail) Send(subject, body string) error {
  10. options := &mail.Options{
  11. MailHost: "smtp.163.com",
  12. MailPort: 465,
  13. MailUser: "xx@163.com",
  14. MailPass: "",
  15. MailTo: "",
  16. Subject: subject,
  17. Body: body,
  18. }
  19. return mail.Send(options)
  20. }
  21. // AlarmVerify 定义符合告警的验证规则
  22. type AlarmVerify func(body []byte) (shouldAlarm bool)
  23. // 需要去实现 AlarmVerify 方法,比如这样:
  24. func alarmVerify(body []byte) (shouldalarm bool) {
  25. if len(body) == 0 {
  26. return true
  27. }
  28. type Response struct {
  29. Code int `json:"code"`
  30. }
  31. resp := new(Response)
  32. if err := json.Unmarshal(body, resp); err != nil {
  33. return true
  34. }
  35. // 当第三方接口返回的 code 不等于约定的成功值(1)时,就要进行告警
  36. return resp.Code != 1
  37. }
  38. // 使用时:
  39. httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), alarmVerify),

设置失败时重试

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

示例

  1. // 以 httpclient.PostForm 为例
  2. api := "http://127.0.0.1:9999/demo/post"
  3. params := url.Values{}
  4. params.Set("name", name)
  5. body, err := httpclient.PostForm(api, params,
  6. httpclient.WithTTL(time.Second*5),
  7. httpclient.WithTrace(ctx.Trace()),
  8. httpclient.WithLogger(ctx.Logger()),
  9. httpclient.WithHeader("Authorization", "xxxx"),
  10. httpclient.WithMock(MockDemoPost),
  11. httpclient.WithOnFailedRetry(3, time.Second*1, retryVerify),
  12. httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), alarmVerify),
  13. )
  14. if err != nil {
  15. return nil, err
  16. }
  17. res = new(demoPostResponse)
  18. err = json.Unmarshal(body, res)
  19. if err != nil {
  20. return nil, errors.Wrap(err, "DemoPost json unmarshal error")
  21. }
  22. if res.Code != 1 {
  23. return nil, errors.New(fmt.Sprintf("code err: %d-%s", res.Code, res.Msg))
  24. }
  25. return res, nil