完成基础反射调用接口 + 数据响应
This commit is contained in:
parent
77ea723e86
commit
e95061a1a8
@ -8,6 +8,7 @@
|
|||||||
package router
|
package router
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -38,25 +39,26 @@ func (c controller) Parse(inputController any) map[string]UriConfig {
|
|||||||
}
|
}
|
||||||
controllerType := reflect.TypeOf(inputController)
|
controllerType := reflect.TypeOf(inputController)
|
||||||
controllerValue := reflect.ValueOf(inputController)
|
controllerValue := reflect.ValueOf(inputController)
|
||||||
if controllerType.Kind() == reflect.Func {
|
/*if controllerType.Kind() == reflect.Func {
|
||||||
// 直接函数注册
|
// 直接函数注册
|
||||||
cfg, isNeedRegister := c.methodConfig(controllerType)
|
cfg, isNeedRegister := c.methodConfig(controllerType)
|
||||||
if isNeedRegister {
|
if isNeedRegister {
|
||||||
parseRes[cfg.Path] = cfg
|
parseRes[cfg.Path] = cfg
|
||||||
}
|
}
|
||||||
return parseRes
|
return parseRes
|
||||||
}
|
}*/
|
||||||
if controllerType.Kind() == reflect.Ptr {
|
if controllerType.Kind() == reflect.Ptr {
|
||||||
controllerValue = controllerValue.Elem()
|
controllerValue = controllerValue.Elem()
|
||||||
}
|
}
|
||||||
if controllerValue.IsNil() {
|
/*if controllerValue.IsNil() {
|
||||||
return parseRes
|
return parseRes
|
||||||
}
|
}*/
|
||||||
for methodIdx := 0; methodIdx < controllerType.NumMethod(); methodIdx++ {
|
for methodIdx := 0; methodIdx < controllerType.NumMethod(); methodIdx++ {
|
||||||
uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx).Type)
|
uriCfg, needRegister := c.methodConfig(controllerType.Method(methodIdx))
|
||||||
if !needRegister {
|
if !needRegister {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
uriCfg.ApiStructValue = controllerValue
|
||||||
parseRes[uriCfg.Path] = uriCfg
|
parseRes[uriCfg.Path] = uriCfg
|
||||||
}
|
}
|
||||||
return parseRes
|
return parseRes
|
||||||
@ -71,7 +73,8 @@ func (c controller) Parse(inputController any) map[string]UriConfig {
|
|||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 16:05 2025/1/27
|
// Date : 16:05 2025/1/27
|
||||||
func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRegister bool) {
|
func (c controller) methodConfig(reflectMethod reflect.Method) (cfg UriConfig, needRegister bool) {
|
||||||
|
methodType := reflectMethod.Type
|
||||||
// num0: 函数声明
|
// num0: 函数声明
|
||||||
// num1: 第一个参数
|
// num1: 第一个参数
|
||||||
// num2: 第二个参数
|
// num2: 第二个参数
|
||||||
@ -89,6 +92,7 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe
|
|||||||
if formType.Kind() == reflect.Ptr {
|
if formType.Kind() == reflect.Ptr {
|
||||||
formType = methodType.In(2).Elem()
|
formType = methodType.In(2).Elem()
|
||||||
}
|
}
|
||||||
|
cfg.FormDataType = formType
|
||||||
metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
metaField, metaFieldExist := formType.FieldByName(FieldNameMeta)
|
||||||
if !metaFieldExist {
|
if !metaFieldExist {
|
||||||
needRegister = false
|
needRegister = false
|
||||||
@ -96,34 +100,37 @@ func (c controller) methodConfig(methodType reflect.Type) (cfg UriConfig, needRe
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析第一个返回值, 要求必须是结构体或者是map
|
// 解析第一个返回值, 要求必须是结构体或者是map
|
||||||
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 {
|
||||||
needRegister = false
|
needRegister = false
|
||||||
return
|
return
|
||||||
}
|
}*/
|
||||||
if methodType.Out(1).Kind().String() != "error" {
|
if methodType.Out(1).Kind().String() != "error" {
|
||||||
// 判断是否是实现 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 == "Error" && // 实现Error方法
|
if methodType.Out(1).Method(j).Name == "Error" && // 实现Error方法
|
||||||
methodType.Out(1).Method(j).Type.NumIn() == 1 && // 没有任何参数
|
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() {
|
||||||
outputErrParse = true
|
outputErrParse = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
fmt.Println(methodType.Out(1).Method(j).Name, methodType.Out(1).Method(j).Type.NumIn(), methodType.Out(1).Method(j).Type.NumOut(), methodType.Out(1).Method(j).Type.Out(0).Kind().String())
|
||||||
}
|
}
|
||||||
if !outputErrParse {
|
if !outputErrParse {
|
||||||
needRegister = false
|
needRegister = false
|
||||||
|
return
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
// 解析meta信息
|
// 解析meta信息
|
||||||
cfg.Path = metaField.Tag.Get(TagNamePath)
|
cfg.Path = metaField.Tag.Get(TagNamePath)
|
||||||
cfg.Method = metaField.Tag.Get(TagNameMethod)
|
cfg.RequestMethod = metaField.Tag.Get(TagNameMethod)
|
||||||
cfg.Desc = metaField.Tag.Get(TagNameDesc)
|
cfg.Desc = metaField.Tag.Get(TagNameDesc)
|
||||||
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
cfg.TagList = strings.Split(metaField.Tag.Get(TagNameUriTag), ",")
|
||||||
// 解析参数配置
|
// 解析参数配置
|
||||||
cfg.ParamList = c.parseParamConfig(formType)
|
cfg.ParamList = c.parseParamConfig(formType)
|
||||||
|
cfg.ApiLogicFunc = reflectMethod
|
||||||
|
needRegister = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,14 +31,15 @@ const (
|
|||||||
//
|
//
|
||||||
// Date : 15:41 2024/7/21
|
// Date : 15:41 2024/7/21
|
||||||
type UriConfig struct {
|
type UriConfig struct {
|
||||||
Path string `json:"path"` // 接口路由, 必须配置
|
Path string `json:"path"` // 接口路由, 必须配置
|
||||||
Method string `json:"method"` // 接口请求方法, 必须配置
|
RequestMethod string `json:"request_method"` // 接口请求方法, 必须配置
|
||||||
TagList []string `json:"tag_list"` // 接口分组
|
TagList []string `json:"tag_list"` // 接口分组
|
||||||
Desc string `json:"desc"` // 接口描述
|
Desc string `json:"desc"` // 接口描述
|
||||||
Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY
|
Strict bool `json:"strict"` // 接口是否为严格模式 : 不配置, 则为严格模式.严格模式 : POST 仅解析 BODY , GET 仅解析 QUERY
|
||||||
ParamList []UriParam `json:"param_list"` // 参数信息表
|
ParamList []UriParam `json:"param_list"` // 参数信息表
|
||||||
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
FormDataType reflect.Type `json:"-"` // 表单数据类型
|
||||||
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
|
ApiStructValue reflect.Value `json:"-"` // 逻辑函数所属结构体取值
|
||||||
|
ApiLogicFunc reflect.Method `json:"-"` // 自定义的接口逻辑
|
||||||
}
|
}
|
||||||
|
|
||||||
// UriParam 接口参数配置
|
// UriParam 接口参数配置
|
||||||
|
@ -26,7 +26,7 @@ func Group(router *gin.Engine, routerPrefix string, middlewareList []gin.Handler
|
|||||||
for _, c := range cList {
|
for _, c := range cList {
|
||||||
urlTable := cParser.Parse(c)
|
urlTable := cParser.Parse(c)
|
||||||
for _, itemUriCfg := range urlTable {
|
for _, itemUriCfg := range urlTable {
|
||||||
method := strings.ToUpper(itemUriCfg.Method)
|
method := strings.ToUpper(itemUriCfg.RequestMethod)
|
||||||
switch method {
|
switch method {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
g.GET(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
g.GET(itemUriCfg.Path, RequestHandler(itemUriCfg))
|
||||||
|
@ -31,10 +31,12 @@ func RequestHandler(uriCfg UriConfig) gin.HandlerFunc {
|
|||||||
formData := reflect.New(uriCfg.FormDataType).Interface()
|
formData := reflect.New(uriCfg.FormDataType).Interface()
|
||||||
// 表单解析
|
// 表单解析
|
||||||
if err = request.Form.Parse(ctx, formData); nil != err {
|
if err = request.Form.Parse(ctx, formData); nil != err {
|
||||||
|
e = exception.NewFromError(400, err)
|
||||||
|
response.SendWithException(ctx, e, nil)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 执行逻辑
|
// 执行逻辑
|
||||||
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{reflect.ValueOf(ctx), reflect.ValueOf(formData)})
|
resList := uriCfg.ApiLogicFunc.Func.Call([]reflect.Value{uriCfg.ApiStructValue, reflect.ValueOf(ctx), reflect.ValueOf(formData)})
|
||||||
if resList[1].IsNil() {
|
if resList[1].IsNil() {
|
||||||
// 请求成功
|
// 请求成功
|
||||||
response.Success(ctx, resList[0].Interface())
|
response.Success(ctx, resList[0].Interface())
|
||||||
|
@ -123,12 +123,12 @@ func parseUriConfig(methodType reflect.Type, routerPrefix string) (*UriConfig, e
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
uriConfig := &UriConfig{
|
uriConfig := &UriConfig{
|
||||||
Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"),
|
Path: strings.TrimRight(routerPrefix, "/") + "/" + strings.TrimLeft(metaField.Tag.Get(TagNamePath), "/"),
|
||||||
Method: strings.ToUpper(metaField.Tag.Get(TagNameMethod)),
|
RequestMethod: strings.ToUpper(metaField.Tag.Get(TagNameMethod)),
|
||||||
TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"),
|
TagList: strings.Split(metaField.Tag.Get(TagNameUriTag), "|"),
|
||||||
Desc: metaField.Tag.Get(TagNameDesc),
|
Desc: metaField.Tag.Get(TagNameDesc),
|
||||||
Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0,
|
Strict: wrapper.ArrayType([]string{"", "true"}).Has(strings.ToLower(metaField.Tag.Get(TagNameStrict))) >= 0,
|
||||||
FormDataType: methodType.In(2).Elem(),
|
FormDataType: methodType.In(2).Elem(),
|
||||||
}
|
}
|
||||||
// 校验 FormDataType
|
// 校验 FormDataType
|
||||||
for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ {
|
for fieldIdx := 0; fieldIdx < uriConfig.FormDataType.NumField(); fieldIdx++ {
|
||||||
@ -174,7 +174,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList
|
|||||||
middlewareList = append([]gin.HandlerFunc{
|
middlewareList = append([]gin.HandlerFunc{
|
||||||
middleware.InitRequest(),
|
middleware.InitRequest(),
|
||||||
}, middlewareList...)
|
}, middlewareList...)
|
||||||
switch uriConfig.Method {
|
switch uriConfig.RequestMethod {
|
||||||
case http.MethodGet:
|
case http.MethodGet:
|
||||||
ginRouter.GET(uriConfig.Path, middlewareList...)
|
ginRouter.GET(uriConfig.Path, middlewareList...)
|
||||||
case http.MethodHead:
|
case http.MethodHead:
|
||||||
@ -196,7 +196,7 @@ func registerUri(uriConfig *UriConfig, methodValue reflect.Value, middlewareList
|
|||||||
case "ANY":
|
case "ANY":
|
||||||
ginRouter.Any(uriConfig.Path, middlewareList...)
|
ginRouter.Any(uriConfig.Path, middlewareList...)
|
||||||
default:
|
default:
|
||||||
panic(uriConfig.Path + " : " + uriConfig.Method + " is not support")
|
panic(uriConfig.Path + " : " + uriConfig.RequestMethod + " is not support")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,24 +15,13 @@ import (
|
|||||||
|
|
||||||
type TestController struct{}
|
type TestController struct{}
|
||||||
|
|
||||||
func (t *TestController) RouterPrefix() string {
|
func (t TestController) Logic(ctx *gin.Context, formData *TestForm) (any, error) {
|
||||||
return "/uri/prefix"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t *TestController) RouterMiddleware() []gin.HandlerFunc {
|
|
||||||
return []gin.HandlerFunc{
|
|
||||||
func(ctx *gin.Context) {
|
|
||||||
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
func (t *TestController) Uri(ctx *gin.Context, formData *TestForm) (any, error) {
|
|
||||||
return formData, nil
|
return formData, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestForm struct {
|
type TestForm struct {
|
||||||
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"`
|
Meta `tag:"测试表单" path:"/a/b/c/d" desc:"测试接口" method:"get" strict:"true"`
|
||||||
Age int `json:"age" form:"age"`
|
Age int `json:"age" form:"age" binding:"min=20"`
|
||||||
Name string `json:"name" form:"name"`
|
Name string `json:"name" form:"name"`
|
||||||
Test *Test `json:"test" form:"test"`
|
Test *Test `json:"test" form:"test"`
|
||||||
Num *int64 `json:"num" form:"num"`
|
Num *int64 `json:"num" form:"num"`
|
||||||
@ -42,8 +31,7 @@ type Test struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Test_parseController(t *testing.T) {
|
func Test_parseController(t *testing.T) {
|
||||||
type args struct {
|
r := gin.Default()
|
||||||
controller any
|
Group(r, "test", nil, TestController{})
|
||||||
}
|
r.Run(":8080")
|
||||||
Register(8080, &TestController{})
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user