支持解析路由前缀

This commit is contained in:
白茶清欢 2024-07-20 23:39:25 +08:00
parent cbfe92597e
commit b14b1ef345
7 changed files with 102 additions and 276 deletions

View File

@ -1,35 +0,0 @@
// Package router ...
//
// Description : 便捷的相关API处理
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-03-26 2:06 下午
package router
import (
"github.com/gin-gonic/gin"
)
// IApi 每一个接口的实现约束
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2:08 下午 2021/3/26
type IApi interface {
// GetMethod 接口请求方法
GetMethod() string
// GetURI 接口URI
GetURI() string
// GetMiddleWareList 使用的中间件列表
GetMiddleWareList() []gin.HandlerFunc
// GetHandler 处理的handler
GetHandler() gin.HandlerFunc
}
// RegisterFunc 注册路由的函数
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:09 下午 2021/3/26
type RegisterFunc func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc)

13
router/define.go Normal file
View File

@ -0,0 +1,13 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-07-20 22:57
package router
const (
PrefixFuncName = "RouterPrefix" // 路由前缀函数名称
MiddlewareFuncName = "RouterMiddleware" // 路由中间件函数名称
)

15
router/meta.go Normal file
View File

@ -0,0 +1,15 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-07-20 21:40
package router
// Meta 接口的元信息
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 21:40 2024/7/20
type Meta struct{}

View File

@ -1,115 +1,69 @@
// Package router ... // Package router ...
// //
// Description : 注册路由 // Description : router ...
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 2021-03-26 2:13 下午 // Date : 2024-07-20 21:39
package router package router
import ( import (
"log" "fmt"
"reflect" "reflect"
"github.com/pkg/errors"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
var ( var (
// DebugLogEnable 默认打开debug日志 ginRouter = gin.Default()
DebugLogEnable = true
) )
// DisableDebugLog 禁用debug日志 func init() {
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2:17 下午 2021/3/26
func DisableDebugLog() {
DebugLogEnable = false
} }
// RegisterRouter 注册一个路由 // Register 注册路由
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 2:14 下午 2021/3/26 // Date : 21:40 2024/7/20
func RegisterRouter(router *gin.Engine, apiInstanceList ...any) error { func Register(port int, controllerList ...any) {
for _, apiInstance := range apiInstanceList { for _, controller := range controllerList {
if nil == apiInstance { if nil == controller {
// 忽略空指针
continue continue
} }
val := reflect.ValueOf(apiInstance)
switch val.Kind() {
case reflect.Struct:
fallthrough
case reflect.Ptr:
api, ok := apiInstance.(IApi)
if ok {
if err := HandleRegisterRouter(router, api.GetMethod(), api.GetURI(), api.GetHandler(), api.GetMiddleWareList()); nil != err {
routerLog(err.Error())
return err
}
continue
}
routerLog(val.String() + "结构体或者结构体指针, 自动识别函数是否包含RouterFunc")
// 不是IApi接口,自动识别函数列表 RouterFunc 函数自动注册
methodCnt := val.NumMethod()
for i := 0; i < methodCnt; i++ {
// TODO : 识别函数本身是不是 RouterFunc
af, o := val.Method(i).Interface().(func() (string, string, gin.HandlerFunc, []gin.HandlerFunc))
if o {
method, uri, handler, middlewareList := af()
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
routerLog(err.Error())
return err
}
continue
}
apiFuncList := val.Method(i).Call(nil)
for _, apiFuncVal := range apiFuncList {
apiFunc, ok := apiFuncVal.Interface().(RegisterFunc)
if !ok {
continue
}
method, uri, handler, middlewareList := apiFunc()
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
routerLog(err.Error())
return err
}
}
}
case reflect.Func:
api, ok := apiInstance.(RegisterFunc)
if !ok {
err := errors.New("函数方式注册路由必须是 RouterFunc")
routerLog(err.Error())
return err
}
method, uri, handler, middlewareList := api()
if err := HandleRegisterRouter(router, method, uri, handler, middlewareList); nil != err {
routerLog(err.Error())
return err
}
default:
err := errors.New("注册的路由必须是 IApi 或者 RouterFunc 或者 包含 RouterFunc 的结构体")
routerLog(err.Error())
return err
}
} }
return nil
} }
// routerLog 记录日志 // parseController 解析controller
// //
// Author : go_developer@163.com<白茶清欢> // Author : go_developer@163.com<白茶清欢>
// //
// Date : 2:28 下午 2021/3/26 // Date : 22:10 2024/7/20
func routerLog(msg string) { func parseController(controller any) {
if !DebugLogEnable || len(msg) == 0 { controllerType := reflect.TypeOf(controller)
return controllerValue := reflect.ValueOf(controller)
routerPrefix := "/"
// 解析路由前缀函数
// routerPrefix 不能有任何入参, 并且只能有一个返回值,
// 返回值类型为字符串, 为具体路由前缀
routerPrefixFunc, routerPrefixFuncExist := controllerType.MethodByName(PrefixFuncName)
if routerPrefixFuncExist {
routerPrefixFuncType := routerPrefixFunc.Type
if routerPrefixFuncType.NumIn() == 1 && // 无任何入参, 正在没有如何入参情况下, 第一个参数是结构体指针
routerPrefixFuncType.NumOut() == 1 && // 只能有一个返回值
routerPrefixFuncType.Out(0).Kind() == reflect.String { // 返回值必须是字符串
routerPrefix = routerPrefixFunc.Func.Call([]reflect.Value{controllerValue})[0].String()
// .Call(nil)[0].String()
}
// 请求组的中间件
/*routerMiddlewareFunc := controllerType.MethodByName(MiddlewareFuncName)
routerMiddlewareFuncType := routerMiddlewareFunc.Type()
if routerMiddlewareFuncType.NumIn() == 0 && // 无需任何参数
routerMiddlewareFuncType.NumOut() == 1 && // 只能有一个返回值
routerMiddlewareFuncType.Out(0).String() == "[]gin.HandlerFunc" { // 返回值必须是gin.HandlerFunc
}*/
} }
log.Print(msg) fmt.Println(routerPrefix)
} }

View File

@ -1,78 +0,0 @@
// Package router ...
//
// Description : 路由注册单元测试
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2021-03-26 3:49 下午
package router
import (
"net/http"
"testing"
"github.com/stretchr/testify/assert"
"github.com/gin-gonic/gin"
)
// TestRegisterRouter ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 3:50 下午 2021/3/26
func TestRegisterRouter(t *testing.T) {
r := gin.Default()
err := RegisterRouter(r, demoApiFunc(), &demoApi{}, &otherApi{}, nil)
assert.Nil(t, err, "路由注册异常 : %v", err)
}
func demoApiFunc() RouterFunc {
return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
return http.MethodGet, "/api/func/test", func(context *gin.Context) {
}, nil
}
}
type demoApi struct {
}
func (d demoApi) GetMethod() string {
return http.MethodGet
}
func (d demoApi) GetURI() string {
return "/api/struct/test"
}
func (d demoApi) GetMiddleWareList() []gin.HandlerFunc {
return nil
}
func (d demoApi) GetHandler() gin.HandlerFunc {
return func(context *gin.Context) {
}
}
type otherApi struct {
}
func (oa *otherApi) DemoApiFunc() RouterFunc {
return func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
return http.MethodGet, "/api/other/test", func(context *gin.Context) {
}, nil
}
}
func (oa *otherApi) Lala() {
}
func (oa *otherApi) SelfApi() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) {
return http.MethodGet, "/api/other/self/test", func(context *gin.Context) {
}, nil
}

36
router/register_test.go Normal file
View File

@ -0,0 +1,36 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-07-20 23:24
package router
import (
"testing"
"github.com/gin-gonic/gin"
)
type TestController struct{}
func (t *TestController) RouterPrefix() string {
return "/uri/prefix"
}
func (t *TestController) RouterMiddleware() []gin.HandlerFunc {
return []gin.HandlerFunc{
func(ctx *gin.Context) {
},
}
}
func Test_parseController(t *testing.T) {
type args struct {
controller any
}
parseController(TestController{})
parseController(&TestController{})
}

View File

@ -1,79 +0,0 @@
// Package router ...
//
// Description : router ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2023-03-03 16:48
package router
import (
"fmt"
"net/http"
"strings"
"github.com/gin-gonic/gin"
)
// HandleRegisterRouter 注册gin路由
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:36 下午 2021/3/9
func HandleRegisterRouter(router *gin.Engine, method string, uri string, handler gin.HandlerFunc, middlewareList []gin.HandlerFunc) error {
if nil == middlewareList {
middlewareList = make([]gin.HandlerFunc, 0)
}
switch strings.ToUpper(method) {
case http.MethodGet:
router.GET(uri, handler).Use(middlewareList...)
case http.MethodPost:
router.POST(uri, handler).Use(middlewareList...)
case http.MethodDelete:
router.DELETE(uri, handler).Use(middlewareList...)
case http.MethodHead:
router.HEAD(uri, handler).Use(middlewareList...)
case http.MethodOptions:
router.OPTIONS(uri, handler).Use(middlewareList...)
case http.MethodPatch:
router.PATCH(uri, handler).Use(middlewareList...)
case http.MethodPut:
router.PUT(uri, handler).Use(middlewareList...)
case "ANY": // 一次性注册全部请求方法的路由
router.Any(uri, handler).Use(middlewareList...)
default:
// 不是一个函数,数名method配置错误
return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method)
}
return nil
}
// RegisterRouterGroup 注册gin路由
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 8:36 下午 2021/3/9
func RegisterRouterGroup(router *gin.RouterGroup, method string, uri string, handler gin.HandlerFunc) error {
switch strings.ToUpper(method) {
case http.MethodGet:
router.GET(uri, handler)
case http.MethodPost:
router.POST(uri, handler)
case http.MethodDelete:
router.DELETE(uri, handler)
case http.MethodHead:
router.HEAD(uri, handler)
case http.MethodOptions:
router.OPTIONS(uri, handler)
case http.MethodPatch:
router.PATCH(uri, handler)
case http.MethodPut:
router.PUT(uri, handler)
case "ANY": // 一次性注册全部请求方法的路由
router.Any(uri, handler)
default:
// 不是一个函数,数名method配置错误
return fmt.Errorf("uri=%s method=%s 请求方法配置错误", uri, method)
}
return nil
}