#14 optimize third_party_request

This commit is contained in:
新亮
2021-03-13 13:53:52 +08:00
parent f7b3dbae5e
commit 5e5db8917d
10 changed files with 176 additions and 153 deletions
@@ -5,7 +5,7 @@ import (
"time"
"github.com/xinliangnote/go-gin-api/internal/api/code"
"github.com/xinliangnote/go-gin-api/internal/api/repository/third_party_request/go_gin_api_repo"
"github.com/xinliangnote/go-gin-api/internal/api/third_party_request/go_gin_api"
"github.com/xinliangnote/go-gin-api/internal/pkg/cache"
"github.com/xinliangnote/go-gin-api/internal/pkg/core"
"github.com/xinliangnote/go-gin-api/pkg/errno"
@@ -34,12 +34,12 @@ type traceResponse []struct {
func (h *handler) Trace() core.HandlerFunc {
return func(c core.Context) {
// 三方请求信息
res1, err := go_gin_api_repo.DemoGet("Tom",
res1, err := go_gin_api.DemoGet("Tom",
httpclient.WithTTL(time.Second*5),
httpclient.WithTrace(c.Trace()),
httpclient.WithLogger(c.Logger()),
httpclient.WithHeader("Authorization", c.GetHeader("Authorization")),
httpclient.WithOnFailedRetry(3, time.Second*1, go_gin_api_repo.DemoGetRetryVerify),
httpclient.WithOnFailedRetry(3, time.Second*1, go_gin_api.DemoGetRetryVerify),
)
if err != nil {
@@ -56,12 +56,12 @@ func (h *handler) Trace() core.HandlerFunc {
p.Println("res1.Name", res1.Name, p.WithTrace(c.Trace()))
// 三方请求信息
res2, err := go_gin_api_repo.DemoPost("Jack",
res2, err := go_gin_api.DemoPost("Jack",
httpclient.WithTTL(time.Second*5),
httpclient.WithTrace(c.Trace()),
httpclient.WithLogger(c.Logger()),
httpclient.WithHeader("Authorization", c.GetHeader("Authorization")),
httpclient.WithOnFailedRetry(3, time.Second*1, go_gin_api_repo.DemoPostRetryVerify),
httpclient.WithOnFailedRetry(3, time.Second*1, go_gin_api.DemoPostRetryVerify),
)
if err != nil {
+1 -8
View File
@@ -4,7 +4,6 @@
- `./db_repo` 访问 DB 数据
- `./cache_repo` 访问 Cache 数据
- `./third_party_request` 访问外部 HTTP 接口数据。
#### SQL 建议:
- 建议每张表需包含字段:主键(id)、标记删除(is_deteled)、创建时间(created_at)、更新时间(updated_at)
@@ -23,10 +22,4 @@
#### 脚本生成 MySQL CURD
1. 定义生成的表,设置 config 中 cmd.genTables,可以自定义设置多张表,为空表示生成库中所有的表,如果设置多个表可用','分割;
1. 在根目录下执行脚本文件:`./scripts/gormgen.sh`
以用户表(user_demo)为例:
- 结构体文件:user_demo_repo/gen_model.go
- CURD 方法文件:user_demo_repo/gen_user_demo.go
- 表结构 MD 文件:user_demo_repo/gen_table.md
- 使用脚本自动生成基于表结构的 CURD 代码,见文档:`./cmd/gormgen/README.md`
@@ -1,21 +0,0 @@
package go_gin_api_repo
import "encoding/json"
func MockDemoGet() (body []byte) {
res := new(demoGetResponse)
res.Name = "AA"
res.Job = "AA_JOB"
body, _ = json.Marshal(res)
return body
}
func MockDemoPost() (body []byte) {
res := new(demoPostResponse)
res.Name = "BB"
res.Job = "BB_JOB"
body, _ = json.Marshal(res)
return body
}
@@ -1,80 +0,0 @@
package go_gin_api_repo
import (
"encoding/json"
"testing"
"time"
"github.com/xinliangnote/go-gin-api/internal/api/repository/third_party_request"
"github.com/xinliangnote/go-gin-api/pkg/httpclient"
)
var authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjEsIlVzZXJOYW1lIjoieGlubGlhbmdub3RlIiwiZXhwIjoxNjEzODI3MTEzLCJpYXQiOjE2MTM3NDA3MTMsIm5iZiI6MTYxMzc0MDcxM30.SnooP1ikO33ryGPdohsmOKqISa-bWzMkMvUNb5f2zc0"
func TestDemoGet(t *testing.T) {
res, err := DemoGet("Tom",
httpclient.WithTTL(time.Second*5),
//httpclient.WithTrace(ctx.Trace()),
//httpclient.WithLogger(ctx.Logger()),
httpclient.WithHeader("Authorization", authorization),
httpclient.WithOnFailedRetry(3, time.Second*1, retryVerify),
httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), alarmVerify),
//httpclient.WithMock(MockDemoGet),
)
if err != nil {
t.Log("get [demo/get] err", err)
}
t.Log(res)
}
func TestDemoPost(t *testing.T) {
res, err := DemoPost("Jack",
httpclient.WithTTL(time.Second*5),
//httpclient.WithTrace(ctx.Trace()),
//httpclient.WithLogger(ctx.Logger()),
httpclient.WithHeader("Authorization", authorization),
httpclient.WithMock(MockDemoPost),
)
if err != nil {
t.Log("post [demo/post] err", err)
}
t.Log(res)
}
// 设置重试规则
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
}
return resp.Code != 1
}
// 设置告警规则
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
}
return resp.Code != 1
}
@@ -1,8 +1,11 @@
package third_party_request
import (
"github.com/xinliangnote/go-gin-api/configs"
"github.com/xinliangnote/go-gin-api/pkg/httpclient"
"github.com/xinliangnote/go-gin-api/pkg/mail"
"github.com/pkg/errors"
)
// 实现 AlarmObject 告警
@@ -10,15 +13,22 @@ var _ httpclient.AlarmObject = (*AlarmEmail)(nil)
type AlarmEmail struct{}
// 邮件告警方式
func (a *AlarmEmail) Send(subject, body string) error {
cfg := configs.Get().Mail
if cfg.Host == "" || cfg.Port == 0 || cfg.User == "" || cfg.Pass == "" || cfg.To == "" {
return errors.New("mail config error")
}
options := &mail.Options{
MailHost: "smtp.163.com",
MailPort: 465,
MailUser: "xx@163.com",
MailPass: "",
MailTo: "",
MailHost: cfg.Host,
MailPort: cfg.Port,
MailUser: cfg.User,
MailPass: cfg.Pass,
MailTo: cfg.To,
Subject: subject,
Body: body,
}
return mail.Send(options)
}
@@ -0,0 +1,63 @@
package go_gin_api
import (
"encoding/json"
"github.com/xinliangnote/go-gin-api/pkg/httpclient"
"github.com/pkg/errors"
)
// 接口地址
var demoGetApi = "http://127.0.0.1:9999/demo/get/"
// 接口返回结构
type demoGetResponse struct {
Name string `json:"name"`
Job string `json:"job"`
}
// 发起请求
func DemoGet(name string, opts ...httpclient.Option) (res *demoGetResponse, err error) {
api := demoGetApi + name
body, err := httpclient.Get(api, nil, opts...)
if err != nil {
return nil, err
}
res = new(demoGetResponse)
err = json.Unmarshal(body, res)
if err != nil {
return nil, errors.Wrap(err, "DemoGet json unmarshal error")
}
return res, nil
}
// 设置重试规则
func DemoGetRetryVerify(body []byte) (shouldRetry bool) {
if len(body) == 0 {
return true
}
return false
}
// 设置告警规则
func DemoGetAlarmVerify(body []byte) (shouldAlarm bool) {
if len(body) == 0 {
return true
}
return false
}
// 设置 Mock 数据
func DemoGetMock() (body []byte) {
res := new(demoGetResponse)
res.Name = "AA"
res.Job = "AA_JOB"
body, _ = json.Marshal(res)
return body
}
@@ -0,0 +1,29 @@
package go_gin_api
import (
"testing"
"time"
"github.com/xinliangnote/go-gin-api/internal/api/third_party_request"
"github.com/xinliangnote/go-gin-api/pkg/httpclient"
)
var demoGetAuthorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjEsIlVzZXJOYW1lIjoieGlubGlhbmdub3RlIiwiZXhwIjoxNjEzODI3MTEzLCJpYXQiOjE2MTM3NDA3MTMsIm5iZiI6MTYxMzc0MDcxM30.SnooP1ikO33ryGPdohsmOKqISa-bWzMkMvUNb5f2zc0"
func TestDemoGet(t *testing.T) {
res, err := DemoGet("Tom",
httpclient.WithTTL(time.Second*5),
//httpclient.WithTrace(ctx.Trace()),
//httpclient.WithLogger(ctx.Logger()),
httpclient.WithHeader("Authorization", demoGetAuthorization),
httpclient.WithOnFailedRetry(3, time.Second*1, DemoGetRetryVerify),
httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), DemoGetAlarmVerify),
httpclient.WithMock(DemoGetMock),
)
if err != nil {
t.Log("get [demo/get] err", err)
}
t.Log(res)
}
@@ -1,4 +1,4 @@
package go_gin_api_repo
package go_gin_api
import (
"encoding/json"
@@ -9,42 +9,18 @@ import (
"github.com/pkg/errors"
)
type demoGetResponse struct {
Name string `json:"name"`
Job string `json:"job"`
}
// 接口地址
var demoPostApi = "http://127.0.0.1:9999/demo/post/"
// 接口返回结构
type demoPostResponse struct {
Name string `json:"name"`
Job string `json:"job"`
}
func DemoGet(name string, opts ...httpclient.Option) (res *demoGetResponse, err error) {
api := "http://127.0.0.1:9999/demo/get/" + name
body, err := httpclient.Get(api, nil, opts...)
if err != nil {
return nil, err
}
res = new(demoGetResponse)
err = json.Unmarshal(body, res)
if err != nil {
return nil, errors.Wrap(err, "DemoGet json unmarshal error")
}
return res, nil
}
func DemoGetRetryVerify(body []byte) (shouldRetry bool) {
if len(body) == 0 {
return true
}
return false
}
// 发起请求
func DemoPost(name string, opts ...httpclient.Option) (res *demoPostResponse, err error) {
api := "http://127.0.0.1:9999/demo/post"
api := demoPostApi
params := url.Values{}
params.Set("name", name)
body, err := httpclient.PostForm(api, params, opts...)
@@ -61,6 +37,7 @@ func DemoPost(name string, opts ...httpclient.Option) (res *demoPostResponse, er
return res, nil
}
// 设置重试规则
func DemoPostRetryVerify(body []byte) (shouldRetry bool) {
if len(body) == 0 {
return true
@@ -68,3 +45,22 @@ func DemoPostRetryVerify(body []byte) (shouldRetry bool) {
return false
}
// 设置告警规则
func DemoPostAlarmVerify(body []byte) (shouldAlarm bool) {
if len(body) == 0 {
return true
}
return false
}
// 设置 Mock 数据
func DemoPostMock() (body []byte) {
res := new(demoPostResponse)
res.Name = "BB"
res.Job = "BB_JOB"
body, _ = json.Marshal(res)
return body
}
@@ -0,0 +1,29 @@
package go_gin_api
import (
"testing"
"time"
"github.com/xinliangnote/go-gin-api/internal/api/third_party_request"
"github.com/xinliangnote/go-gin-api/pkg/httpclient"
)
var demoPostAuthorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJVc2VySUQiOjEsIlVzZXJOYW1lIjoieGlubGlhbmdub3RlIiwiZXhwIjoxNjEzODI3MTEzLCJpYXQiOjE2MTM3NDA3MTMsIm5iZiI6MTYxMzc0MDcxM30.SnooP1ikO33ryGPdohsmOKqISa-bWzMkMvUNb5f2zc0"
func TestDemoPost(t *testing.T) {
res, err := DemoPost("Jack",
httpclient.WithTTL(time.Second*5),
//httpclient.WithTrace(ctx.Trace()),
//httpclient.WithLogger(ctx.Logger()),
httpclient.WithHeader("Authorization", demoPostAuthorization),
httpclient.WithOnFailedRetry(3, time.Second*1, DemoPostRetryVerify),
httpclient.WithOnFailedAlarm("接口告警", new(third_party_request.AlarmEmail), DemoPostAlarmVerify),
httpclient.WithMock(DemoPostMock),
)
if err != nil {
t.Log("post [demo/post] err", err)
}
t.Log(res)
}
+8 -4
View File
@@ -273,13 +273,17 @@ func New(logger *zap.Logger, options ...Option) (Mux, error) {
}
if !opt.disablePProf {
pprof.Register(mux.engine) // register pprof to gin
fmt.Println(color.Green("* [register pprof]"))
if !env.Active().IsPro() {
pprof.Register(mux.engine) // register pprof to gin
fmt.Println(color.Green("* [register pprof]"))
}
}
if !opt.disableSwagger {
mux.engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // register swagger
fmt.Println(color.Green("* [register swagger]"))
if !env.Active().IsPro() {
mux.engine.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // register swagger
fmt.Println(color.Green("* [register swagger]"))
}
}
if !opt.disablePrometheus {