优化升级gin框架的二次包装 #19
@@ -52,10 +52,6 @@ func (c controller) Parse(inputController any) map[string]UriConfig {
|
|||||||
// 参数 : 方法反射结果
|
// 参数 : 方法反射结果
|
||||||
//
|
//
|
||||||
// 返回值 : 第一个 -> 解析出的接口配置 第二个 -> 是否要注册为接口
|
// 返回值 : 第一个 -> 解析出的接口配置 第二个 -> 是否要注册为接口
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 16:05 2025/1/27
|
|
||||||
func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, needRegister bool) {
|
func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, needRegister bool) {
|
||||||
methodType := reflectMethod.Type
|
methodType := reflectMethod.Type
|
||||||
// num0: 函数声明
|
// num0: 函数声明
|
||||||
@@ -71,7 +67,7 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
|||||||
needRegister = false
|
needRegister = false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 解析第二个参数是组合Meta的form表单
|
// 解析第二个参数是组合 Meta 的form表单
|
||||||
formType := methodType.In(2)
|
formType := methodType.In(2)
|
||||||
cfg.FormDataType = formType
|
cfg.FormDataType = formType
|
||||||
if formType.Kind() == reflect.Ptr {
|
if formType.Kind() == reflect.Ptr {
|
||||||
@@ -89,7 +85,7 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
|||||||
// 判断是否是实现 error接口的方法
|
// 判断是否是实现 error接口的方法
|
||||||
outputErrParse := false
|
outputErrParse := false
|
||||||
for j := 0; j < methodType.Out(1).NumMethod(); j++ {
|
for j := 0; j < methodType.Out(1).NumMethod(); j++ {
|
||||||
if methodType.Out(1).Method(j).Name == ErrorInterfaceFuncName && // 实现Error方法
|
if methodType.Out(1).Method(j).Name == ErrorInterfaceFuncName && // 实现 Error 方法
|
||||||
methodType.Out(1).Method(j).Type.NumIn() == 0 && // 没有任何参数
|
methodType.Out(1).Method(j).Type.NumIn() == 0 && // 没有任何参数
|
||||||
methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值
|
methodType.Out(1).Method(j).Type.NumOut() == 1 && // 一个返回值
|
||||||
methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() {
|
methodType.Out(1).Method(j).Type.Out(0).Kind().String() == reflect.String.String() {
|
||||||
@@ -102,16 +98,8 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 解析meta信息
|
c.setUriMeta(metaField, &cfg)
|
||||||
cfg.Path = metaField.Tag.Get(TagNamePath)
|
|
||||||
cfg.RequestMethod = metaField.Tag.Get(TagNameMethod)
|
|
||||||
cfg.Desc = metaField.Tag.Get(TagNameDesc)
|
|
||||||
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
|
||||||
// 解析第一个返回值, 要求必须是结构体或者是map
|
|
||||||
outputStrictModel := metaField.Tag.Get(TagNameOutputStrict)
|
|
||||||
hookSync := strings.ToLower(metaField.Tag.Get(TagNameHookSync))
|
|
||||||
cfg.HookSync = hookSync == "1" || hookSync == "true" // 同步执行判断
|
|
||||||
cfg.OutputStrict = outputStrictModel == "1" || outputStrictModel == "true"
|
|
||||||
if cfg.OutputStrict {
|
if cfg.OutputStrict {
|
||||||
// 开启输出严格模式校验
|
// 开启输出严格模式校验
|
||||||
if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map {
|
if methodType.Out(0).Kind() != reflect.Struct && methodType.Out(0).Kind() != reflect.Map {
|
||||||
@@ -119,6 +107,7 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析参数配置
|
// 解析参数配置
|
||||||
//cfg.ParamList = c.parseParamConfig(formType)
|
//cfg.ParamList = c.parseParamConfig(formType)
|
||||||
cfg.ApiLogicFunc = reflectMethod
|
cfg.ApiLogicFunc = reflectMethod
|
||||||
@@ -126,24 +115,21 @@ func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, n
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseParamConfig 解析参数配置
|
// setUriMeta 设置接口的 meta 信息
|
||||||
//
|
func (c controller) setUriMeta(metaField reflect.StructField, cfg *UriConfig) {
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
// 解析 meta 信息
|
||||||
//
|
cfg.Path = metaField.Tag.Get(TagNamePath) // 接口路由
|
||||||
// Date : 14:35 2025/2/7
|
cfg.RequestMethod = strings.Split(strings.ToUpper(metaField.Tag.Get(TagNameMethod)), ",") // 请求方法
|
||||||
func (c controller) parseParamConfig(formDataType reflect.Type) []UriParam {
|
cfg.Desc = metaField.Tag.Get(TagNameDesc) // 接口描述
|
||||||
res := make([]UriParam, 0)
|
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",") // 接口标签
|
||||||
for i := 0; i < formDataType.NumField(); i++ {
|
// 以下是bool类型的配置解析
|
||||||
structField := formDataType.Field(i)
|
var boolMetaParse = func(tagName string) bool {
|
||||||
if structField.Name == FieldNameMeta {
|
val := strings.ToLower(metaField.Tag.Get(tagName))
|
||||||
// Meta 字段, 忽略
|
return val == "1" || val == "true"
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
jsonTag := structField.Tag.Get("json")
|
cfg.OutputStrict = boolMetaParse(TagNameOutputStrict) // 配置接口数据是否严格要求是对象
|
||||||
if jsonTag == "" {
|
cfg.HookSync = boolMetaParse(TagNameHookSync) // 同步执行判断
|
||||||
jsonTag = structField.Name
|
cfg.IsWebsocket = boolMetaParse(TagNameIsWebsocket) // 是否是 websocket 接口
|
||||||
}
|
cfg.IsSse = boolMetaParse(TagNameIsSse) // 是否是 sse 接口
|
||||||
|
cfg.NoLogin = boolMetaParse(TagNameNoLogin) // 是否需要登录
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,25 +24,27 @@ const (
|
|||||||
TagNameMethod = "method" // 接口的请求方法
|
TagNameMethod = "method" // 接口的请求方法
|
||||||
TagNameUriTag = "tag" // 接口的 tag
|
TagNameUriTag = "tag" // 接口的 tag
|
||||||
TagNameDesc = "desc" // 接口的描述
|
TagNameDesc = "desc" // 接口的描述
|
||||||
|
TagNameIsSse = "is-sse" // 是否 SSE 连接
|
||||||
|
TagNameIsWebsocket = "is-ws" // 是否 websocket 连接
|
||||||
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
TagNameOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map,非严格模式返回任意值
|
||||||
TagNameHookSync = "hook-sync" // hook 同步执行
|
TagNameHookSync = "hook-sync" // hook 同步执行
|
||||||
|
TagNameNoLogin = "no-login" // 接口是否需要登录(无需登录, 则有token就验证, 无token不验证)
|
||||||
TagNameBinding = "binding" // gin 内置的验证规则tag
|
TagNameBinding = "binding" // gin 内置的验证规则tag
|
||||||
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
TagNameValidate = "validate" // validator v10 默认的验证规则tag
|
||||||
TagNameErrMsg = "err" // 验证失败错误信息 tag
|
TagNameErrMsg = "err" // 验证失败错误信息 tag
|
||||||
)
|
)
|
||||||
|
|
||||||
// UriConfig 接口配置
|
// UriConfig 接口配置
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 15:41 2024/7/21
|
|
||||||
type UriConfig struct {
|
type UriConfig struct {
|
||||||
Path string `json:"path"` // 接口路由, 必须配置
|
Path string `json:"path"` // 接口路由, 必须配置
|
||||||
RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
|
RequestMethod []string `json:"request_method"` // 接口请求方法, 必须配置
|
||||||
TagList []string `json:"tag_list"` // 接口分组
|
TagList []string `json:"tag_list"` // 接口分组
|
||||||
Desc string `json:"desc"` // 接口描述
|
Desc string `json:"desc"` // 接口描述
|
||||||
|
IsSse bool `json:"is_sse"` // 是否 SSE 连接
|
||||||
|
IsWebsocket bool `json:"is_ws"` // 是否 websocket 连接
|
||||||
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
|
OutputStrict bool `json:"output_strict"` // 接口是否为严格模式 : 不配置,可返回任意类型, 配置, 必须返回结构体或者map
|
||||||
HookSync bool `json:"hook_sync"` // 接口主逻辑执行完成之后,hook是否同步执行, 默认异步执行
|
HookSync bool `json:"hook_sync"` // 接口主逻辑执行完成之后,hook是否同步执行, 默认异步执行
|
||||||
|
NoLogin bool `json:"no_login"` // 接口是否需要登录(无需登录, 则有token就验证, 无token不验证)
|
||||||
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||||
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
|
ResultDataType reflect.Type `json:"-"` // 返回值数据类型
|
||||||
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
||||||
|
|||||||
@@ -135,10 +135,6 @@ type server struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start 启动服务
|
// Start 启动服务
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 18:31 2025/2/7
|
|
||||||
func (s *server) Start() {
|
func (s *server) Start() {
|
||||||
// 注册文档
|
// 注册文档
|
||||||
s.uiInstance.RegisterHandler(s.router, s.option.swaggerBaseUri)
|
s.uiInstance.RegisterHandler(s.router, s.option.swaggerBaseUri)
|
||||||
@@ -153,28 +149,16 @@ func (s *server) Start() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Router 对外访问路由实例, 不建议直接用
|
// Router 对外访问路由实例, 不建议直接用
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 17:35 2025/2/18
|
|
||||||
func (s *server) Router() *gin.Engine {
|
func (s *server) Router() *gin.Engine {
|
||||||
return s.router
|
return s.router
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handler404 注册404的处理方法
|
// Handler404 注册404的处理方法
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 16:01 2025/2/22
|
|
||||||
func (s *server) Handler404(f gin.HandlerFunc) {
|
func (s *server) Handler404(f gin.HandlerFunc) {
|
||||||
s.router.NoRoute(f)
|
s.router.NoRoute(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCustomRouter 自定义路由处理
|
// SetCustomRouter 自定义路由处理
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 16:09 2025/2/22
|
|
||||||
func (s *server) SetCustomRouter(f func(r *gin.Engine)) {
|
func (s *server) SetCustomRouter(f func(r *gin.Engine)) {
|
||||||
if nil == f {
|
if nil == f {
|
||||||
return
|
return
|
||||||
@@ -183,10 +167,6 @@ func (s *server) SetCustomRouter(f func(r *gin.Engine)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Group 注册接口路由
|
// Group 注册接口路由
|
||||||
//
|
|
||||||
// Author : go_developer@163.com<白茶清欢>
|
|
||||||
//
|
|
||||||
// Date : 19:35 2025/1/27
|
|
||||||
func (s *server) Group(routerPrefix string, middlewareList []gin.HandlerFunc, cList ...any) {
|
func (s *server) Group(routerPrefix string, middlewareList []gin.HandlerFunc, cList ...any) {
|
||||||
g := s.router.Group(routerPrefix)
|
g := s.router.Group(routerPrefix)
|
||||||
g.Use(middlewareList...)
|
g.Use(middlewareList...)
|
||||||
@@ -195,8 +175,9 @@ func (s *server) Group(routerPrefix string, middlewareList []gin.HandlerFunc, cL
|
|||||||
urlTable := cParser.Parse(c)
|
urlTable := cParser.Parse(c)
|
||||||
for _, itemUriCfg := range urlTable {
|
for _, itemUriCfg := range urlTable {
|
||||||
_ = s.uiInstance.DocInstance().AddApiFromInAndOut(routerPrefix, itemUriCfg.FormDataType, itemUriCfg.ResultDataType)
|
_ = s.uiInstance.DocInstance().AddApiFromInAndOut(routerPrefix, itemUriCfg.FormDataType, itemUriCfg.ResultDataType)
|
||||||
method := strings.ToUpper(itemUriCfg.RequestMethod)
|
|
||||||
handleFunc := s.RequestHandler(itemUriCfg)
|
handleFunc := s.RequestHandler(itemUriCfg)
|
||||||
|
// 一个接口支持注册多种请求方法
|
||||||
|
for _, method := range itemUriCfg.RequestMethod {
|
||||||
switch method {
|
switch method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
g.GET(itemUriCfg.Path, handleFunc)
|
g.GET(itemUriCfg.Path, handleFunc)
|
||||||
@@ -215,7 +196,8 @@ func (s *server) Group(routerPrefix string, middlewareList []gin.HandlerFunc, cL
|
|||||||
case http.MethodTrace:
|
case http.MethodTrace:
|
||||||
panic(`method Trace is not supported`)
|
panic(`method Trace is not supported`)
|
||||||
default:
|
default:
|
||||||
panic("method " + itemUriCfg.RequestMethod + " is not support")
|
panic("method " + method + " is not support")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user