引入 GinWrapperContext, gateway待升级测试

This commit is contained in:
白茶清欢 2025-03-10 14:44:20 +08:00
parent 28da213bb8
commit ab78127317
8 changed files with 59 additions and 17 deletions

12
define/request.go Normal file
View File

@ -0,0 +1,12 @@
// Package define ...
//
// Description : define ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2025-03-10 14:38
package define
const (
GinWrapperContextKey = "GIN_WRAPPER_CONTEXT"
)

View File

@ -67,7 +67,7 @@ func NewContext(ginContext *gin.Context) *Context {
return &Context{
Context: ginContext,
StartRequestTime: time.Now(),
FinishRequestTime: time.Time(int64(0)),
FinishRequestTime: time.Unix(0, 0),
HandlerAfterResponse: make([]gin.HandlerFunc, 0),
customData: make(map[string]any),
Hostname: hostname,

View File

@ -326,3 +326,21 @@ func (wh *wrapperHandle) GetLogicAfterResponse(ctx *gin.Context) *define.LogicAf
// 就这么写, key值如果被其他人覆盖成非法值, 此处会直接panic
return l.(*define.LogicAfterResponse)
}
// GetGinWrapperContext 获取包装之后context
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 14:41 2025/3/10
func (wh *wrapperHandle) GetGinWrapperContext(ctx *gin.Context) *Context {
if nil == ctx {
return nil
}
if val, exist := ctx.Get(define.GinWrapperContextKey); !exist || nil == val {
newCtx := NewContext(ctx)
newCtx.SetCustom(define.GinWrapperContextKey, newCtx)
return newCtx
} else {
return val.(*Context)
}
}

View File

@ -70,7 +70,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
return
}
// 第一个参数必须是 *gin.Context
if methodType.In(1).String() != GinContextType {
firstParamStr := methodType.In(1).String()
if firstParamStr != GinContextType && firstParamStr != GinWrapperContextType {
needRegister = false
return
}
@ -105,6 +106,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
return
}
}
// 是否gin包装后的context
cfg.IsGinWrapperContext = firstParamStr == GinWrapperContextType
// 解析meta信息
cfg.Path = metaField.Tag.Get(TagNamePath)
cfg.RequestMethod = metaField.Tag.Get(TagNameMethod)

View File

@ -15,6 +15,7 @@ const (
PrefixFuncName = "RouterPrefix" // 路由前缀函数名称
MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称
GinContextType = "*gin.Context" // gin context 类型名称
GinWrapperContextType = "*request.Context" // gin context 类型名称
ErrorType = "error" // error类型
ErrorInterfaceFuncName = "Error" // error接口需要实现的方法名称
)
@ -36,15 +37,16 @@ const (
//
// Date : 15:41 2024/7/21
type UriConfig struct {
Path string `json:"path"` // 接口路由, 必须配置
RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
TagList []string `json:"tag_list"` // 接口分组
Desc string `json:"desc"` // 接口描述
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
FormDataType reflect.Type `json:"-"` // 表单数据类型
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
Path string `json:"path"` // 接口路由, 必须配置
RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
TagList []string `json:"tag_list"` // 接口分组
Desc string `json:"desc"` // 接口描述
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
FormDataType reflect.Type `json:"-"` // 表单数据类型
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
IsGinWrapperContext bool `json:"is_gin_wrapper_context"` // 是否gin包装后的context
}
// UriParam 接口参数配置

View File

@ -79,7 +79,14 @@ func RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
if uriCfg.FormDataType.Kind() != reflect.Ptr {
inputValue = inputValue.Elem()
}
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, reflect.ValueOf(ctx), inputValue})
ginWrapperContext := request.NewContext(ctx)
// wrapper context 设置到 gin context
ginWrapperContext.Set(define.GinWrapperContextKey, ginWrapperContext)
ctxReflect := reflect.ValueOf(ctx)
if uriCfg.IsGinWrapperContext {
ctxReflect = reflect.ValueOf(ginWrapperContext)
}
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, ctxReflect, inputValue})
if resList[1].IsNil() {
// 请求成功
isSuccess = true

View File

@ -109,8 +109,9 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e
}
// 接口logic共计两个参数. 两个返回值, 格式 : func(ctx *gin.Context, formData any[组合Meta]) (any[response], error)
// 解析第一个参数是 *gin.Context
if methodType.In(1).String() != "*gin.Context" {
// 解析第一个参数是 *gin.Context / 或者包装后的 request.Context
firstParamStr := methodType.In(1).String()
if firstParamStr != "*gin.Context" && firstParamStr != "*request.Context" {
return nil, nil
}
// 解析第二个参数是组合Meta的form表单

View File

@ -8,14 +8,13 @@
package router
import (
"git.zhangdeman.cn/zhangdeman/gin/request"
"testing"
"github.com/gin-gonic/gin"
)
type TestController struct{}
func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (TestOut, error) {
func (t TestController) Logic(ctx *request.Context, formData *TestForm) (TestOut, error) {
return TestOut{
FormData: formData,
}, nil