Skip to content

Instantly share code, notes, and snippets.

@marcus-crane
Created June 16, 2021 01:49
Show Gist options
  • Save marcus-crane/54ad429fac92296d652e4190b0f36ae3 to your computer and use it in GitHub Desktop.
Save marcus-crane/54ad429fac92296d652e4190b0f36ae3 to your computer and use it in GitHub Desktop.
Fiber golang example of showing child routes a la Django Rest Framework (could be improved)
package routes
import (
"sort"
"strings"
"github.com/gofiber/fiber/v2"
)
func Register(app *fiber.App) *fiber.App {
listChildRoutes := func(c *fiber.Ctx) error {
routeList := getRouteChildren(c.Route().Path, app.Stack())
return c.JSON(fiber.Map{
"success": true,
"children": routeList,
})
}
app.Get("/", listChildRoutes)
api := app.Group("/api")
api.Get("/", listChildRoutes)
v1 := api.Group("/v1")
v1.Get("/", listChildRoutes)
responders := v1.Group("/responders")
responders.Get("/", listChildRoutes)
return app
}
func getRouteChildren(currentRoute string, routeStack [][]*fiber.Route) []string {
currentRoute = normaliseRoute(currentRoute)
getMethodList := routeStack[0] // First entry contains GET routes, second contains POST etc
childRoutes := []string{}
currRouteLen := 0
if currentRoute != "/" {
currRouteLen = len(strings.Split(currentRoute, "/")) - 1 // -1 to ignore whitespace from string split
}
for _, route := range getMethodList {
path := normaliseRoute(route.Path)
if path == currentRoute {
continue
}
routeLength := len(strings.Split(path, "/")) - 1
if strings.Contains(path, currentRoute) && currRouteLen+1 == routeLength {
childRoutes = append(childRoutes, path)
}
}
sort.Strings(childRoutes)
return childRoutes
}
func normaliseRoute(route string) string {
// Annoyingly, if you register "/api" and "/api/", the trailing slash isn't removed internally
if route == "/" {
return route
}
lastChar := route[len(route)-1:]
if lastChar == "/" {
route = route[0 : len(route)-1]
}
return route
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment