diff --git a/define/context.go b/define/context.go index 525abd7..7c470b2 100644 --- a/define/context.go +++ b/define/context.go @@ -10,9 +10,9 @@ package define import ( "context" httpclientDefine "git.zhangdeman.cn/gateway/httpclient/define" + validatorDefine "git.zhangdeman.cn/gateway/validator/define" "git.zhangdeman.cn/zhangdeman/trace" "sync" - "time" ) // RequestContext 请求配置 @@ -21,18 +21,13 @@ import ( // // Date : 17:19 2024/11/11 type RequestContext struct { - ctx context.Context `json:"-"` // gin 上下文 - runtimeInstance *trace.Runtime `json:"-"` // 链路统一追踪实例 - lock *sync.RWMutex `json:"-"` // 数据锁 - GatewayUrlConfig *GatewayApiConfig `json:"gateway_url_config"` // 网关接口的配置 - GatewayApiInfo *GatewayApi `json:"gateway_api_info"` // 网关接口信息 - GatewayRequest *GatewayRequestInfo `json:"gateway_request"` // 网关请求信息 - BackendApiResultTable map[string]*httpclientDefine.Response `json:"backend_api_result_table"` // 后端接口返回数据详细信息: 接口别名 => 请求结果 - AppApiPermission *AppApiPermission `json:"app_api_permission"` // 应用接口权限 - AppApiResultPermissionList []*AppApiResultPermission `json:"app_api_result_permission_list"` // 应用接口返回值权限 - AppRateBehavior RateBehavior `json:"app_rate_behavior"` // 应用没有配置流控限制的行为 - ProjectRateLimit map[string]*RateLimitConfig `json:"project_rate_behavior"` // 项目流控行为 - ResponseData *ResponseData `json:"response_data"` // 网关响应数据 + ctx context.Context `json:"-"` // gin 上下文 + runtimeInstance *trace.Runtime `json:"-"` // 链路统一追踪实例 + lock *sync.RWMutex `json:"-"` // 数据锁 + TraceID string `json:"trace_id"` // 全链路追踪的trace_id + GatewayUrlConfig *ApiConfig `json:"gateway_url_config"` // 网关接口的配置 + RequestInfo *RequestInfo `json:"request_info"` // 网关请求信息 + BackendApiResultTable map[string]*httpclientDefine.Response `json:"backend_api_result_table"` // 后端接口返回数据详细信息: 接口别名 => 请求结果 } func (rc *RequestContext) Lock() { @@ -51,13 +46,12 @@ func (rc *RequestContext) RUnlock() { rc.lock.RUnlock() } -// GatewayApiConfig 网关接口配置 +// ApiConfig 网关接口配置 // // Author : go_developer@163.com<白茶清欢> // // Date : 10:41 2024/11/13 -type GatewayApiConfig struct { - RateLimit *RateLimit `json:"rate_limit"` // 网关接口流控规则 +type ApiConfig struct { Uri string `json:"uri"` // 网关接口ID ContentType string `json:"content_type"` // 请求类型 Method string `json:"method"` // 请求方法 @@ -69,12 +63,6 @@ type GatewayApiConfig struct { RequestRewriteTable map[string][]*RequestRewriteItem `json:"request_rewrite_table"` // 请求重写规则, 项目接口别名ID => 重写规则列表 } -type RateLimit struct { - ProjectTable map[int64]*RateLimitCfg `json:"project_table"` // 项目流控 - ProjectApiTable map[int64]*RateLimitCfg `json:"project_api_table"` // 项目接口流控 - Gateway *RateLimitCfg `json:"gateway"` // 网关接口本身流控 -} - // GatewayApiDetailProjectApiParamItem 项目接口参数 // // Author : go_developer@163.com<白茶清欢> @@ -147,15 +135,15 @@ type Result struct { // // Date : 11:20 2024/11/13 type Param struct { - Location string `json:"location"` // 参数位置 - Path string `json:"path"` // 参数路径 - ParamType string `json:"param_type"` // 参数类型 - DefaultValue string `json:"default_value"` // 默认值 - IsRequired bool `json:"is_required"` // 是否必传 - AllowEmpty bool `json:"allow_empty"` // 空字符串是否为有效参数 - AllowZero bool `json:"allow_zero"` // 数字类型, 0 是否为有效参数 - AllowNil bool `json:"allow_nil"` // nil 是否为有效参数 - ValidateRule any `json:"validate_rule"` // 校验规则 : TODO : 预留 + Location string `json:"location"` // 参数位置 + Path string `json:"path"` // 参数路径 + ParamType string `json:"param_type"` // 参数类型 + DefaultValue string `json:"default_value"` // 默认值 + IsRequired bool `json:"is_required"` // 是否必传 + AllowEmpty bool `json:"allow_empty"` // 空字符串是否为有效参数 + AllowZero bool `json:"allow_zero"` // 数字类型, 0 是否为有效参数 + AllowNil bool `json:"allow_nil"` // nil 是否为有效参数 + ValidateRule *validatorDefine.FieldRule `json:"validate_rule"` // 校验规则 } // ServiceApiConfig 服务接口配置 @@ -168,7 +156,6 @@ type ServiceApiConfig struct { ServiceApiFlag string `json:"service_api_flag"` // 服务接口标识 CacheEnable bool `json:"cache_enable"` // 缓存是否可用 CacheInstanceID int64 `json:"cache_instance_id"` // 缓存可用的情况下, 缓存实例ID - CacheConfig *ApiCacheConfig `json:"cache_config"` // 缓存配置 FullUrl string `json:"full_url"` // 项目接口完整Url CodeField string `json:"code_field"` // 状态码字段 MessageField string `json:"message_field"` // 状态码描述字段 @@ -180,124 +167,19 @@ type ServiceApiConfig struct { ResultList []*GatewayApiDetailProjectApiResultItem `json:"result_list"` // 项目接口返回值列表 } -type RateLimitCfg struct { - Day int `json:"day"` // 每天限制 - Hour int `json:"hour"` // 每小时限制 - Minute int `json:"minute"` // 每分钟限制 - Second int `json:"second"` // 每秒限制 -} - -type ApiCacheConfig struct { - PreHeatEnable bool `json:"pre_heat_enable"` // 启用预热 - ForcePreHeat bool `json:"force_pre_heat"` // 强制预热 - PreHeatMinPercent int64 `json:"pre_heat_min_percent"` // 预热最小剩余百分比 - PreHeatMinTTL int64 `json:"pre_heat_min_ttl"` // 预热最小剩余时长 - CacheTime int64 `json:"cache_time"` // 缓存时长, 单位 : s -} - -type GatewayApiDetail struct { - RateLimit *RateLimit `json:"rate_limit"` // 网关接口流控规则 - GatewayApiID int64 `json:"gateway_api_id"` // 网关接口ID - Uri string `json:"uri"` // 网关接口ID - ContentType string `json:"content_type"` // 请求类型 - Method string `json:"method"` // 请求方法 - Version string `json:"version"` // 接口版本 - Name string `json:"name"` // 接口名称 - Status string `json:"status"` // 状态 - ParamList []*Param `json:"param_list"` // 参数列表 - ResultList []*Result `json:"result_list"` // 返回值列表 - ProjectApiTable map[int64]*ServiceApiConfig `json:"project_api_table"` // 项目接口列表 - RequestRewriteTable map[string][]*RequestRewriteItem `json:"request_rewrite_table"` // 请求重写规则, 项目接口别名ID => 重写规则列表 -} - -type GatewayApi struct { - ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID - GroupID int64 `json:"group_id" gorm:"column:group_id;default:0;NOT NULL"` // 接口分组ID - Version string `json:"version" gorm:"column:version;default:v1;NOT NULL"` // 接口版本 - Uri string `json:"uri" gorm:"column:uri;default:;NOT NULL"` // 网关对外暴露的URI - MethodID int64 `json:"method_id" gorm:"column:method_id;default:0;NOT NULL"` // 请求方法ID - ContentTypeID int64 `json:"content_type_id" gorm:"column:content_type_id;default:0;NOT NULL"` // 请求类型ID - Name string `json:"name" gorm:"column:name;default:;NOT NULL"` // 网关API名称 - ExtendRule string `json:"extend_rule" gorm:"column:extend_rule;default:[];NOT NULL"` // 同名请求参数不存在时的参数规则 - Description string `json:"description" gorm:"column:description;default:;NOT NULL"` // 网关API描述 - Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 NORMAL - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 - Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 - CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID - ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID - CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 - ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 -} - -type GatewayRequestInfo struct { - Header map[string]string `json:"header"` // header信息 - Cookie map[string]string `json:"cookie"` // cookie信息 - Query map[string]string `json:"query"` // cookie信息 - Body map[string]any `json:"body"` // body信息 - Method string `json:"method"` // 请求方法 - Domain string `json:"domain"` // 域名 - ContentType string `json:"content_type"` // 请求类型 - Scheme string `json:"scheme"` // scheme - Uri string `json:"uri"` // 接口uri - Filter any `json:"filter_request"` // 过滤之后的请求信息 -} - -type AppApiPermission struct { - ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID - AppID int64 `json:"app_id" gorm:"column:app_id;default:0;NOT NULL"` // 应用ID - GatewayApiID int64 `json:"gateway_api_id" gorm:"column:gateway_api_id;default:0;NOT NULL"` // 网关接口ID - PerSecond int `json:"per_second" gorm:"column:per_second;default:0;NOT NULL"` // 全局每秒访问限制, 默认为 0 - 不限制 - PerMinute int `json:"per_minute" gorm:"column:per_minute;default:0;NOT NULL"` // 全局每分钟访问限制, 默认为 0 - 不限制 - PerHour int `json:"per_hour" gorm:"column:per_hour;default:0;NOT NULL"` // 全局每小时访问限制, 默认为 0 - 不限制 - PerDay int `json:"per_day" gorm:"column:per_day;default:0;NOT NULL"` // 全局每天访问限制, 默认为 0 - 不限制 - ItemTokenCount int `json:"item_token_count" gorm:"column:item_token_count;default:1;NOT NULL"` // 每次访问消耗的令牌数 - Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 USING - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 - Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 - CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID - ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID - CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 - ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 -} - -type AppApiResultPermission struct { - ID int64 `json:"id" gorm:"column:id;default:;NOT NULL"` // 主键ID - AppID int64 `json:"app_id" gorm:"column:app_id;default:0;NOT NULL"` // 应用ID - AppApiPermissionID int64 `json:"app_api_permission_id" gorm:"column:app_api_permission_id;default:0;NOT NULL"` // 接口授权ID - GatewayApiResultID int64 `json:"gateway_api_result_id" gorm:"column:gateway_api_result_id;default:0;NOT NULL"` // 网关接口返回值ID - Status string `json:"status" gorm:"column:status;default:INIT;NOT NULL"` // 状态 INIT - 待启用 USING - 可用中 FORBIDDEN - 禁用 OFFLINE - 下线 DELETE - 删除 - Importance int64 `json:"importance" gorm:"column:importance;default:0;NOT NULL"` // 数据重要等级, 0 - 10 之间的数字 - CreateUserID string `json:"create_user_id" gorm:"column:create_user_id;default:0;NOT NULL"` // 创建人ID - ModifyUserID string `json:"modify_user_id" gorm:"column:modify_user_id;default:0;NOT NULL"` // 修改人ID - CreateTime time.Time `json:"create_time" gorm:"column:create_time;default:current_timestamp;NOT NULL"` // 创建时间 - ModifyTime time.Time `json:"modify_time" gorm:"column:modify_time;default:current_timestamp;NOT NULL"` // 修改时间 -} - -type RateBehavior struct { - Day string `json:"day"` // 每天的处理 - Hour string `json:"hour"` // 每小时的处理 - Minute string `json:"minute"` // 每分钟的处理 - Second string `json:"second"` // 每秒中的处理 - SetRateLimitFail string `json:"set_rate_limit_fail"` // 设置流控失败的行为 -} - -type RateLimitConfig struct { - DayTotal int64 `json:"day_total"` // 每天总次数 - Day int64 `json:"day"` // 每天的次数 - DayZeroRateLimitBehavior string `json:"day_zero_rate_limit_behavior"` // 天未配置流控行为 - HourTotal int64 `json:"hour_total"` // 每小时总次数 - Hour int64 `json:"hour"` // 每小时的次数 - HourZeroRateLimitBehavior string `json:"hour_zero_rate_limit_behavior"` // 小时未配置流控行为 - MinuteTotal int64 `json:"minute_total"` // 每分钟总次数 - Minute int64 `json:"minute"` // 每分钟的次数 - MinuteZeroRateLimitBehavior string `json:"minute_zero_rate_limit_behavior"` // 分钟未配置流控行为 - SecondTotal int64 `json:"second_total"` // 每秒钟总次数 - Second int64 `json:"second"` // 每秒中的次数 - SecondZeroRateLimitBehavior string `json:"second_zero_rate_limit_behavior"` // 未配置流控行为 - SetRateLimitFail string `json:"set_rate_limit_fail"` // 流控失败的行为 -} - -type ResponseData struct { - Body map[string]any `json:"body"` // body数据 - Header map[string]string `json:"header"` // header数据 - Cookie map[string]string `json:"cookie"` // cookie数据 - SourceData string `json:"source_data"` // 原始body数据 +// RequestInfo ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 15:47 2024/11/13 +type RequestInfo struct { + Header map[string]string `json:"header"` // header信息 + Cookie map[string]string `json:"cookie"` // cookie信息 + Query map[string]string `json:"query"` // cookie信息 + Body map[string]any `json:"body"` // body信息 + Method string `json:"method"` // 请求方法 + Domain string `json:"domain"` // 域名 + ContentType string `json:"content_type"` // 请求类型 + Scheme string `json:"scheme"` // scheme + Uri string `json:"uri"` // 接口uri } diff --git a/go.mod b/go.mod index 705d043..9ec43d4 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.23.3 require ( git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763 // indirect + git.zhangdeman.cn/gateway/validator v0.0.0-20241101105100-4367435ab7d1 // indirect git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3 // indirect git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect @@ -21,6 +22,7 @@ require ( github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect + github.com/tidwall/sjson v1.2.5 // indirect golang.org/x/net v0.31.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 271ad6e..1b56477 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763 h1:g0njPNnh1BDilE1YHYEykAkc/NXHIphRE8jCnN0pT/0= git.zhangdeman.cn/gateway/httpclient v0.0.0-20241024134801-faef35748763/go.mod h1:+zqRzmRb5m7RlmKyYUeONJYj4z9Ftytf5yMD59w+ziM= +git.zhangdeman.cn/gateway/validator v0.0.0-20241101105100-4367435ab7d1 h1:eajAGqdBI9mFShNbD0q+3hK4+ITHy2MFv6fieYf15r0= +git.zhangdeman.cn/gateway/validator v0.0.0-20241101105100-4367435ab7d1/go.mod h1:x4AI7MT/7WPr+oC9EOkM4BNgQYn+YF9l/qAnIA1Xyrc= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3 h1:BiAlBJ+DuRs/xD7nDQD2JT8Oc+V+0Uwt36qZwdXGvzI= git.zhangdeman.cn/zhangdeman/consts v0.0.0-20241104082108-0f97a870bbc3/go.mod h1:IXXaZkb7vGzGnGM5RRWrASAuwrVSNxuoe0DmeXx5g6k= git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 h1:s6d4b6yY+NaK1AzoBD1pxqsuygEHQz0Oie86c45geDw= @@ -28,6 +30,7 @@ github.com/mozillazg/go-pinyin v0.20.0 h1:BtR3DsxpApHfKReaPO1fCqF4pThRwH9uwvXzm+ github.com/mozillazg/go-pinyin v0.20.0/go.mod h1:iR4EnMMRXkfpFVV5FMi4FNB6wGq9NV6uDWbUuPhP4Yc= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -35,6 +38,8 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=