请求配置验证, 默认值初始化 + 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
|
// Date : 17:10 2024/5/24
|
||||||
type Request struct {
|
type Request struct {
|
||||||
Body map[string]any `json:"body"` // 请求Body
|
Body map[string]any `json:"body"` // 请求Body
|
||||||
Header map[string]string `json:"header"` // 请求Header
|
Header map[string]string `json:"header"` // 请求Header
|
||||||
Cookie map[string]string `json:"cookie"` // 请求Cookie
|
Cookie map[string]string `json:"cookie"` // 请求Cookie
|
||||||
Query map[string]string `json:"query"` // 请求query
|
Query map[string]string `json:"query"` // 请求query
|
||||||
FullUrl string `json:"full_url"` // 完整的请求URL
|
FullUrl string `json:"full_url"` // 完整的请求URL
|
||||||
ContentType string `json:"content_type"` // 请求类型
|
ContentType string `json:"content_type"` // 请求类型
|
||||||
Method string `json:"method"` // 请求方法
|
Method string `json:"method"` // 请求方法
|
||||||
DataField string `json:"data_field"` // 数据字段
|
DataField string `json:"data_field"` // 数据字段
|
||||||
CodeField string `json:"code_field"` // 业务状态码字段
|
CodeField string `json:"code_field"` // 业务状态码字段
|
||||||
MessageField string `json:"message_field"` // code描述字段
|
MessageField string `json:"message_field"` // code描述字段
|
||||||
RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则
|
SuccessCodeList []string `json:"success_code_list"` // 哪些业务状态码视为成功
|
||||||
|
ConnectTimeout int64 `json:"connect_timeout"` // 连接超时时间: ms
|
||||||
|
ReadTimeout int64 `json:"read_timeout"` // 读取超时时间
|
||||||
|
RetryRule *RequestRetryRule `json:"retry_rule"` // 重试规则
|
||||||
}
|
}
|
||||||
|
|
||||||
// RequestRetryRule 重试规则
|
// RequestRetryRule 重试规则
|
||||||
@ -37,3 +40,15 @@ type RequestRetryRule struct {
|
|||||||
RetryHttpCodeList []int64 `json:"retry_http_code_list"` // 哪些http状态码需要重试
|
RetryHttpCodeList []int64 `json:"retry_http_code_list"` // 哪些http状态码需要重试
|
||||||
RetryBusinessCodeList []string `json:"retry_business_code_list"` // 哪些业务状态码需要重试
|
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
|
go 1.22.3
|
||||||
|
|
||||||
|
require github.com/go-resty/resty/v2 v2.13.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14 // indirect
|
git.zhangdeman.cn/gateway/validator v0.0.0-20240517061043-10dc8547cc14 // indirect
|
||||||
git.zhangdeman.cn/zhangdeman/consts v0.0.0-20240517060653-203cc568fbec // 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/BurntSushi/toml v1.3.2 // indirect
|
||||||
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 // indirect
|
||||||
github.com/go-ini/ini v1.67.0 // 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/mitchellh/go-homedir v1.1.0 // indirect
|
||||||
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
github.com/mozillazg/go-pinyin v0.20.0 // indirect
|
||||||
github.com/spaolacci/murmur3 v1.1.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