Skip to content

Commit

Permalink
added routes loader
Browse files Browse the repository at this point in the history
  • Loading branch information
VikashChauhan51 committed Jul 27, 2024
1 parent db78329 commit b2de866
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 31 deletions.
25 changes: 5 additions & 20 deletions cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"net/http"
"time"

"github.com/VikashChauhan51/go-sample-api/cmd/api/routes"
Expand Down Expand Up @@ -44,26 +43,12 @@ func main() {
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerfiles.Handler))
v1 := r.Group("/api/v1")
{
for _, route := range *routes.GetRoutes(db) {
switch route.Method {
case http.MethodGet:
v1.GET(route.Path, route.Handler)
case http.MethodPost:
v1.POST(route.Path, route.Handler)
case http.MethodPut:
v1.PUT(route.Path, route.Handler)
case http.MethodPatch:
v1.PATCH(route.Path, route.Handler)
case http.MethodDelete:
v1.DELETE(route.Path, route.Handler)
case http.MethodOptions:
v1.OPTIONS(route.Path, route.Handler)
case http.MethodHead:
v1.HEAD(route.Path, route.Handler)
default:
fmt.Printf("Warning: Unsupported HTTP verb '%s' in route %s\n", route.Method, route.Path)
}
allRoutes, err := routes.ScanRoutes(db)
if err != nil {
fmt.Printf("failed to load routes: %v\n", err)
return
}
routes.RegisterRoutes(v1, allRoutes)
}

r.Run()
Expand Down
24 changes: 24 additions & 0 deletions cmd/api/routes/book_routes.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package routes

import (
"net/http"

"github.com/VikashChauhan51/go-sample-api/internal/controllers"
"github.com/VikashChauhan51/go-sample-api/internal/core/interfaces"
"github.com/VikashChauhan51/go-sample-api/internal/infra/repositories"
"github.com/VikashChauhan51/go-sample-api/internal/infra/services"
"github.com/gin-gonic/gin"
)

func GetBookRoutes(db interfaces.Database) []Route {
bookRepository := repositories.NewBookRepository(db)
bookService := services.NewBookService(bookRepository)
bookController := controllers.NewBookController(bookService)
// Defind all routes
return []Route{
{"GET", "/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "hello world"})
}},
{"GET", "/books", bookController.GetBooks},
}
}
56 changes: 56 additions & 0 deletions cmd/api/routes/loader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package routes

import (
"fmt"
"os"
"path/filepath"
"plugin"
"strings"

"github.com/VikashChauhan51/go-sample-api/internal/core/interfaces"
)

// ScanRoutes scans all route files in the current directory and collects routes.
func ScanRoutes(db interfaces.Database) ([]Route, error) {
var allRoutes []Route

// Find all *_routes.go files in the current directory
err := filepath.Walk(".", func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if strings.HasSuffix(info.Name(), "_routes.go") {
routes, err := loadRoutesFromPlugin(path, db)
if err != nil {
return err
}
allRoutes = append(allRoutes, routes...)
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to scan route files: %v", err)
}

return allRoutes, nil
}

// loadRoutesFromPlugin loads routes from a plugin file.
func loadRoutesFromPlugin(path string, db interfaces.Database) ([]Route, error) {
p, err := plugin.Open(path)
if err != nil {
return nil, fmt.Errorf("failed to open plugin %s: %v", path, err)
}

sym, err := p.Lookup("Routes")
if err != nil {
return nil, fmt.Errorf("failed to find GetRoutes in plugin %s: %v", path, err)
}

getRoutesFunc, ok := sym.(func(interfaces.Database) []Route)
if !ok {
return nil, fmt.Errorf("GetRoutes function has incorrect signature in plugin %s", path)
}

return getRoutesFunc(db), nil
}
32 changes: 21 additions & 11 deletions cmd/api/routes/routes.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package routes

import (
"fmt"
"net/http"

"github.com/VikashChauhan51/go-sample-api/internal/controllers"
"github.com/VikashChauhan51/go-sample-api/internal/core/interfaces"
"github.com/VikashChauhan51/go-sample-api/internal/infra/repositories"
"github.com/VikashChauhan51/go-sample-api/internal/infra/services"
"github.com/gin-gonic/gin"
)

Expand All @@ -16,12 +13,25 @@ type Route struct {
Handler gin.HandlerFunc
}

func GetRoutes(db interfaces.Database) *[]Route {
// Defind all routes
return &[]Route{
{"GET", "/", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{"data": "hello world"})
}},
{"GET", "/books", controllers.NewBookController(services.NewBookService(repositories.NewBookRepository(db))).GetBooks},
func RegisterRoutes(r *gin.RouterGroup, routes []Route) {
for _, route := range routes {
switch route.Method {
case http.MethodGet:
r.GET(route.Path, route.Handler)
case http.MethodPost:
r.POST(route.Path, route.Handler)
case http.MethodPut:
r.PUT(route.Path, route.Handler)
case http.MethodPatch:
r.PATCH(route.Path, route.Handler)
case http.MethodDelete:
r.DELETE(route.Path, route.Handler)
case http.MethodOptions:
r.OPTIONS(route.Path, route.Handler)
case http.MethodHead:
r.HEAD(route.Path, route.Handler)
default:
fmt.Printf("Warning: Unsupported HTTP verb '%s' in route %s\n", route.Method, route.Path)
}
}
}

0 comments on commit b2de866

Please sign in to comment.