From 7b5f89cbe339bceacc9dc89bfd16eed10b8e046c Mon Sep 17 00:00:00 2001 From: hokamsingh Date: Fri, 23 Aug 2024 12:19:49 +0530 Subject: [PATCH] feat: container and module registration, sub-routing --- internal/core/module/module.go | 4 +++- internal/core/router/router.go | 27 ++++++++++++++++++++++++- internal/utils/utils.go | 37 +++++++++++++++++++++------------- pkg/lessgo/less.go | 21 +++++++++++++------ 4 files changed, 67 insertions(+), 22 deletions(-) diff --git a/internal/core/module/module.go b/internal/core/module/module.go index f87eb3e..9175697 100644 --- a/internal/core/module/module.go +++ b/internal/core/module/module.go @@ -8,15 +8,17 @@ type IModule interface { type Module struct { Name string + submodules []IModule Controllers []interface{} Services []interface{} } -func NewModule(name string, controllers []interface{}, services []interface{}) *Module { +func NewModule(name string, controllers []interface{}, services []interface{}, submodules []IModule) *Module { return &Module{ Name: name, Controllers: controllers, Services: services, + submodules: submodules, } } diff --git a/internal/core/router/router.go b/internal/core/router/router.go index 5dd0d2d..d4683ab 100644 --- a/internal/core/router/router.go +++ b/internal/core/router/router.go @@ -6,6 +6,7 @@ import ( "net/http" "path/filepath" "runtime/debug" + "sync" "time" "github.com/gorilla/mux" @@ -29,6 +30,23 @@ var _ = middleware.CORSOptions{ AllowedHeaders: []string{"Content-Type", "Authorization"}, } +var ( + appInstance *Router + once sync.Once +) + +// SetAppInstance sets the singleton App instance. +func SetAppInstance(app *Router) { + once.Do(func() { + appInstance = app + }) +} + +// GetAppInstance returns the singleton App instance. +func GetApp() *Router { + return appInstance +} + // NewRouter creates a new Router with optional configuration. // You can pass options like WithCORS or WithJSONParser to configure the router. // @@ -48,6 +66,7 @@ func NewRouter(options ...Option) *Router { } // Apply default CORS options // r.Use(middleware.NewCORSMiddleware(defaultCORSOptions)) + SetAppInstance(r) return r } @@ -66,6 +85,12 @@ func (r *Router) SubRouter(pathPrefix string, options ...Option) *Router { for _, opt := range options { opt(subRouter) } + + // Apply the middleware to the subrouter's Mux + for _, m := range subRouter.middleware { + subRouter.Mux.Use(m.Handle) + } + return subRouter } @@ -300,7 +325,7 @@ func UnWrapCustomHandler(handler http.HandlerFunc) CustomHandler { // // Example usage: // -// r.AddRoute("/example", func(ctx *context.Context) { +// r.AddRoute("/example", func(ctx *LessGo.Context) { // ctx.JSON(http.StatusOK, map[string]string{"message": "Hello, world!"}) // }) func (r *Router) withContext(next CustomHandler, method string) http.HandlerFunc { diff --git a/internal/utils/utils.go b/internal/utils/utils.go index 470e781..e237681 100644 --- a/internal/utils/utils.go +++ b/internal/utils/utils.go @@ -9,7 +9,6 @@ import ( "path/filepath" "github.com/hokamsingh/lessgo/internal/core/controller" - "github.com/hokamsingh/lessgo/internal/core/di" "github.com/hokamsingh/lessgo/internal/core/module" "github.com/hokamsingh/lessgo/internal/core/router" ) @@ -34,25 +33,35 @@ func GetFolderPath(folderName string) (string, error) { // RegisterModuleRoutes is a helper function to register routes for a module. // It will panic if there is an error during registration or if a controller does not implement the required interface. -func RegisterModuleRoutes(container *di.Container, r *router.Router, _ interface{}) { - err := container.Invoke(func(module module.IModule) { - for _, ctrl := range module.GetControllers() { - c, ok := ctrl.(controller.Controller) - if !ok { - panic(fmt.Sprintf("Controller %T does not implement controller.Controller interface", ctrl)) - } - c.RegisterRoutes(r) +func RegisterModuleRoutes(r *router.Router, m module.IModule) { + for _, ctrl := range m.GetControllers() { + c, ok := ctrl.(controller.Controller) + if !ok { + panic(fmt.Sprintf("Controller %T does not implement controller.Controller interface", ctrl)) } - }) - if err != nil { - panic(fmt.Sprintf("Container invocation failed: %v", err)) + c.RegisterRoutes(r) } } +// func RegisterModuleRoutes(container *di.Container, r *router.Router, _ interface{}) { +// err := container.Invoke(func(module module.IModule) { +// for _, ctrl := range module.GetControllers() { +// c, ok := ctrl.(controller.Controller) +// if !ok { +// panic(fmt.Sprintf("Controller %T does not implement controller.Controller interface", ctrl)) +// } +// c.RegisterRoutes(r) +// } +// }) +// if err != nil { +// panic(fmt.Sprintf("Container invocation failed: %v", err)) +// } +// } + // RegisterModules iterates over a slice of modules and registers their routes. -func RegisterModules(r *router.Router, container *di.Container, modules []module.IModule) error { +func RegisterModules(r *router.Router, modules []module.IModule) error { for _, module := range modules { - RegisterModuleRoutes(container, r, module) + RegisterModuleRoutes(r, module) log.Print("LessGo :: Registered module ", module.GetName()) } return nil diff --git a/pkg/lessgo/less.go b/pkg/lessgo/less.go index 6b037e9..691ecfd 100644 --- a/pkg/lessgo/less.go +++ b/pkg/lessgo/less.go @@ -33,6 +33,15 @@ type CORSMiddleware = middleware.CORSMiddleware type RateLimiterMiddleware = middleware.RateLimiter type FileUploadMiddleware = middleware.FileUploadMiddleware +// VARS +var ( + app = router.GetApp() +) + +func GetApp() *Router { + return app +} + // LoadConfig loads the configuration func LoadConfig() config.Config { config := config.LoadConfig() @@ -45,8 +54,8 @@ func NewContainer() *Container { } // NewModule creates a new module -func NewModule(name string, controllers []interface{}, services []interface{}) *Module { - return module.NewModule(name, controllers, services) +func NewModule(name string, controllers []interface{}, services []interface{}, submodules []IModule) *Module { + return module.NewModule(name, controllers, services, submodules) } // NewRouter creates a new Router with optional configuration @@ -93,13 +102,13 @@ func GetFolderPath(folderName string) (string, error) { return utils.GetFolderPath(folderName) } -func RegisterModuleRoutes(r *router.Router, container *di.Container, module module.Module) { - utils.RegisterModuleRoutes(container, r, module) +func RegisterModuleRoutes(r *router.Router, module module.Module) { + utils.RegisterModuleRoutes(r, &module) } // RegisterModules iterates over a slice of modules and registers their routes. -func RegisterModules(r *router.Router, container *di.Container, modules []IModule) error { - return utils.RegisterModules(r, container, modules) +func RegisterModules(r *router.Router, modules []IModule) error { + return utils.RegisterModules(r, modules) } func GenerateRandomToken(len int) (string, error) {