请求配置验证, 默认值初始化 + full_url + method验证
This commit is contained in:
parent
c977bc0392
commit
2be9c90b79
90
client.go
Normal file
90
client.go
Normal file
@ -0,0 +1,90 @@
|
||||
// Package httpclient ...
|
||||
//
|
||||
// Description : httpclient ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-05-31 15:22
|
||||
package httpclient
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/gateway/httpclient/define"
|
||||
"git.zhangdeman.cn/gateway/httpclient/validate"
|
||||
"github.com/go-resty/resty/v2"
|
||||
)
|
||||
|
||||
// NewHttpClient 获取http client
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:27 2024/5/31
|
||||
func NewHttpClient(reqConfig *define.Request) (*HttpClient, error) {
|
||||
hc := &HttpClient{
|
||||
Client: NewRestyClient(reqConfig),
|
||||
reqConfig: reqConfig,
|
||||
}
|
||||
// 验证配置正确性以及初始化默认值
|
||||
if err := validate.RequestConfig(reqConfig); nil != err {
|
||||
return nil, err
|
||||
}
|
||||
return hc, nil
|
||||
}
|
||||
|
||||
// HttpClient 请求客户端
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:27 2024/5/31
|
||||
type HttpClient struct {
|
||||
*resty.Client
|
||||
reqConfig *define.Request
|
||||
}
|
||||
|
||||
// getRequestValidateMiddleware 请求验证的Middleware
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:40 2024/5/31
|
||||
func (hc *HttpClient) getRequestValidateMiddleware() resty.RequestMiddleware {
|
||||
return func(client *resty.Client, request *resty.Request) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// getResponseValidateMiddleware 获取相应数据验证的middleware
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:42 2024/5/31
|
||||
func (hc *HttpClient) getResponseValidateMiddleware() resty.ResponseMiddleware {
|
||||
return func(client *resty.Client, response *resty.Response) error {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// SetRestyClient 设置client
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:54 2024/5/31
|
||||
func (hc *HttpClient) SetRestyClient(restyClient *resty.Client) {
|
||||
hc.Client = restyClient
|
||||
}
|
||||
|
||||
// GetRestyClient 获取 resty client
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:57 2024/5/31
|
||||
func (hc *HttpClient) GetRestyClient() *resty.Client {
|
||||
return hc.Client
|
||||
}
|
||||
|
||||
// Request 发送请求
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:52 2024/5/31
|
||||
func (hc *HttpClient) Request(reqConfig *define.Request) *define.Response {
|
||||
return nil
|
||||
}
|
17
define/error.go
Normal file
17
define/error.go
Normal file
@ -0,0 +1,17 @@
|
||||
// Package define ...
|
||||
//
|
||||
// Description : define ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-05-31 16:02
|
||||
package define
|
||||
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrRequestConfigNil = errors.New("REQUEST_CONFIG_NIL") // 请求配置 nil
|
||||
ErrFullUrlEmpty = errors.New("FULL_URL_EMPTY") // 没传 full_url
|
||||
ErrFullUrlInvalid = errors.New("FULL_URL_Invalid") // 请求 full_url 不是 http 或者 https 开头
|
||||
ErrMethodIsNotSupport = errors.New("METHOD_IS_NOT_SUPPORT") // 请求 method不支持
|
||||
)
|
@ -13,17 +13,20 @@ package define
|
||||
//
|
||||
// Date : 17:10 2024/5/24
|
||||
type Request struct {
|
||||
Body map[string]any `json:"body"` // 请求Body
|
||||
Header map[string]string `json:"header"` // 请求Header
|
||||
Cookie map[string]string `json:"cookie"` // 请求Cookie
|
||||
Query map[string]string `json:"query"` // 请求query
|
||||
FullUrl string `json:"full_url"` // 完整的请求URL
|
||||
ContentType string `json:"content_type"` // 请求类型
|
||||
Method string `json:"method"` // 请求方法
|
||||
DataField string `json:"data_field"` // 数据字段
|
||||
CodeField string `json:"code_field"` // 业务状态码字段
|
||||
MessageField string `json:"message_field"` // code描述字段
|
||||
RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则
|
||||
Body map[string]any `json:"body"` // 请求Body
|
||||
Header map[string]string `json:"header"` // 请求Header
|
||||
Cookie map[string]string `json:"cookie"` // 请求Cookie
|
||||
Query map[string]string `json:"query"` // 请求query
|
||||
FullUrl string `json:"full_url"` // 完整的请求URL
|
||||
ContentType string `json:"content_type"` // 请求类型
|
||||
Method string `json:"method"` // 请求方法
|
||||
DataField string `json:"data_field"` // 数据字段
|
||||
CodeField string `json:"code_field"` // 业务状态码字段
|
||||
MessageField string `json:"message_field"` // code描述字段
|
||||
SuccessCodeList []string `json:"success_code_list"` // 哪些业务状态码视为成功
|
||||
ConnectTimeout int64 `json:"connect_timeout"` // 连接超时时间: ms
|
||||
ReadTimeout int64 `json:"read_timeout"` // 读取超时时间
|
||||
RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则
|
||||
}
|
||||
|
||||
// RequestRetryRule 重试规则
|
||||
@ -37,3 +40,15 @@ type RequestRetryRule struct {
|
||||
RetryHttpCodeList []int64 `json:"retry_http_code_list"` // 哪些http状态码需要重试
|
||||
RetryBusinessCodeList []string `json:"retry_business_code_list"` // 哪些业务状态码需要重试
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultConnectTimeout = 1000 // 默认连接超时时间
|
||||
DefaultReadTimeout = 1000 // 默认连接读取时间
|
||||
DefaultCodeField = "code" // 默认业务状态码字段
|
||||
DefaultMessageField = "message" // 默认状态码描述字段
|
||||
DefaultDataField = "data" // 默认数据字段
|
||||
)
|
||||
|
||||
var (
|
||||
DefaultSuccessCodeList = []string{"0"} // 默认成功业务状态码
|
||||
)
|
||||
|
3
go.mod
3
go.mod
@ -2,6 +2,8 @@ module git.zhangdeman.cn/gateway/httpclient
|
||||
|
||||
go 1.22.3
|
||||
|
||||
require github.com/go-resty/resty/v2 v2.13.1
|
||||
|
||||
require (
|
||||
git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14 // indirect
|
||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec // indirect
|
||||
@ -13,7 +15,6 @@ require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||
github.com/go-ini/ini v1.67.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.13.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
|
44
resty.go
Normal file
44
resty.go
Normal file
@ -0,0 +1,44 @@
|
||||
// Package httpclient ...
|
||||
//
|
||||
// Description : httpclient ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-05-31 14:59
|
||||
package httpclient
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/gateway/httpclient/define"
|
||||
"github.com/go-resty/resty/v2"
|
||||
"net/textproto"
|
||||
)
|
||||
|
||||
// NewRestyClient 获取resty client
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:00 2024/5/31
|
||||
func NewRestyClient(requestConfig *define.Request) *resty.Client {
|
||||
formatHeader(requestConfig)
|
||||
client := resty.New()
|
||||
if nil == requestConfig {
|
||||
return client
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// formatHeader 格式化header
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 15:18 2024/5/31
|
||||
func formatHeader(requestConfig *define.Request) {
|
||||
if nil == requestConfig {
|
||||
return
|
||||
}
|
||||
formatHeaderData := make(map[string]string)
|
||||
for headerName, headerVal := range requestConfig.Header {
|
||||
formatHeaderData[textproto.CanonicalMIMEHeaderKey(headerName)] = headerVal
|
||||
}
|
||||
requestConfig.Header = formatHeaderData
|
||||
}
|
114
validate/request_config.go
Normal file
114
validate/request_config.go
Normal file
@ -0,0 +1,114 @@
|
||||
// Package validate ...
|
||||
//
|
||||
// Description : validate ...
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 2024-05-31 16:18
|
||||
package validate
|
||||
|
||||
import (
|
||||
"git.zhangdeman.cn/gateway/httpclient/define"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RequestConfig 验证请求配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:18 2024/5/31
|
||||
func RequestConfig(reqConfig *define.Request) error {
|
||||
if nil == reqConfig {
|
||||
return define.ErrRequestConfigNil
|
||||
}
|
||||
rc := &requestConfig{}
|
||||
if err := rc.validateFullUrl(reqConfig); nil != err {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type requestConfig struct {
|
||||
}
|
||||
|
||||
// initDefaultConfig 初始化默认配置
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:25 2024/5/31
|
||||
func (rc *requestConfig) initDefaultConfig(reqConfig *define.Request) {
|
||||
if reqConfig.ConnectTimeout <= 0 {
|
||||
reqConfig.ConnectTimeout = define.DefaultConnectTimeout
|
||||
}
|
||||
if reqConfig.ReadTimeout <= 0 {
|
||||
reqConfig.ReadTimeout = define.DefaultReadTimeout
|
||||
}
|
||||
reqConfig.CodeField = strings.TrimSpace(reqConfig.CodeField)
|
||||
reqConfig.MessageField = strings.TrimSpace(reqConfig.MessageField)
|
||||
reqConfig.DataField = strings.TrimSpace(reqConfig.DataField)
|
||||
if len(reqConfig.CodeField) == 0 {
|
||||
reqConfig.CodeField = define.DefaultCodeField
|
||||
}
|
||||
if len(reqConfig.MessageField) == 0 {
|
||||
reqConfig.MessageField = define.DefaultMessageField
|
||||
}
|
||||
if len(reqConfig.DataField) == 0 {
|
||||
reqConfig.DataField = define.DefaultDataField
|
||||
}
|
||||
if len(reqConfig.SuccessCodeList) == 0 {
|
||||
reqConfig.SuccessCodeList = define.DefaultSuccessCodeList
|
||||
}
|
||||
}
|
||||
|
||||
// validateFullUrl 验证full url
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:17 2024/5/31
|
||||
func (rc *requestConfig) validateFullUrl(reqConfig *define.Request) error {
|
||||
// 验证 full url
|
||||
reqConfig.FullUrl = strings.TrimSpace(reqConfig.FullUrl)
|
||||
if len(reqConfig.FullUrl) == 0 {
|
||||
return define.ErrFullUrlEmpty
|
||||
}
|
||||
if !strings.HasPrefix(reqConfig.FullUrl, "http://") && !strings.HasPrefix(reqConfig.FullUrl, "https://") {
|
||||
return define.ErrFullUrlInvalid
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateMethod 验证method
|
||||
//
|
||||
// Author : go_developer@163.com<白茶清欢>
|
||||
//
|
||||
// Date : 16:22 2024/5/31
|
||||
func (rc *requestConfig) validateMethod(reqConfig *define.Request) error {
|
||||
// 验证Method
|
||||
reqConfig.Method = strings.ToUpper(reqConfig.Method)
|
||||
if len(reqConfig.Method) == 0 {
|
||||
return define.ErrFullUrlEmpty
|
||||
}
|
||||
supportMethodList := []string{
|
||||
http.MethodGet,
|
||||
http.MethodHead,
|
||||
http.MethodPost,
|
||||
http.MethodPut,
|
||||
http.MethodPatch,
|
||||
http.MethodDelete,
|
||||
http.MethodConnect,
|
||||
http.MethodOptions,
|
||||
http.MethodTrace,
|
||||
}
|
||||
isSupportMethod := false
|
||||
for _, item := range supportMethodList {
|
||||
if item == reqConfig.Method {
|
||||
isSupportMethod = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !isSupportMethod {
|
||||
return define.ErrMethodIsNotSupport
|
||||
}
|
||||
return nil
|
||||
}
|
Loading…
Reference in New Issue
Block a user