From f68f691dd1c4d69dc5b5ba4eedc2c2a20cf41e48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 3 Mar 2023 16:52:18 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E9=83=A8=E5=88=86=E5=B7=B2?= =?UTF-8?q?=E6=9C=89=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- router/api.go | 35 ++++++++++ router/register.go | 115 +++++++++++++++++++++++++++++++++ router/register_router_test.go | 78 ++++++++++++++++++++++ router/util.go | 79 ++++++++++++++++++++++ 4 files changed, 307 insertions(+) create mode 100644 router/api.go create mode 100644 router/register.go create mode 100644 router/register_router_test.go create mode 100644 router/util.go diff --git a/router/api.go b/router/api.go new file mode 100644 index 0000000..9e3d71c --- /dev/null +++ b/router/api.go @@ -0,0 +1,35 @@ +// 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 +} + +// RouterFunc 注册路由的函数 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 3:09 下午 2021/3/26 +type RouterFunc func() (method string, uri string, handlerFunc gin.HandlerFunc, middlewareList []gin.HandlerFunc) diff --git a/router/register.go b/router/register.go new file mode 100644 index 0000000..653e30f --- /dev/null +++ b/router/register.go @@ -0,0 +1,115 @@ +// Package router ... +// +// Description : 注册路由 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2021-03-26 2:13 下午 +package router + +import ( + "log" + "reflect" + + "github.com/pkg/errors" + + "github.com/gin-gonic/gin" +) + +var ( + // DebugLogEnable 默认打开debug日志 + DebugLogEnable = true +) + +// DisableDebugLog 禁用debug日志 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:17 下午 2021/3/26 +func DisableDebugLog() { + DebugLogEnable = false +} + +// RegisterRouter 注册一个路由 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:14 下午 2021/3/26 +func RegisterRouter(router *gin.Engine, apiInstanceList ...interface{}) error { + for _, apiInstance := range apiInstanceList { + if nil == apiInstance { + 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().(RouterFunc) + 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.(RouterFunc) + 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 记录日志 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2:28 下午 2021/3/26 +func routerLog(msg string) { + if !DebugLogEnable || len(msg) == 0 { + return + } + log.Print(msg) +} diff --git a/router/register_router_test.go b/router/register_router_test.go new file mode 100644 index 0000000..b7eae00 --- /dev/null +++ b/router/register_router_test.go @@ -0,0 +1,78 @@ +// 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 +} diff --git a/router/util.go b/router/util.go new file mode 100644 index 0000000..7670113 --- /dev/null +++ b/router/util.go @@ -0,0 +1,79 @@ +// 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 +}