package rest import ( "net/http" "path" "strings" "github.com/gin-gonic/gin" ) type Middleware = gin.HandlerFunc type Route struct { Method string Path string Handler gin.HandlerFunc } type Server struct { router *gin.Engine } type routeOptions struct { prefix string middleware []Middleware } type RouteOption func(*routeOptions) func NewGinServer(router *gin.Engine) *Server { return &Server{router: router} } func WithMiddlewares(middlewares []Middleware, routes ...Route) []Route { for i := range routes { routes[i].Handler = chain(middlewares, routes[i].Handler) } return routes } func WithPrefix(prefix string) RouteOption { return func(options *routeOptions) { options.prefix = prefix } } func WithJwt(_ string) RouteOption { return func(*routeOptions) {} } func WithJwtTransition(_, _ string) RouteOption { return func(*routeOptions) {} } func WithSignature(_ any) RouteOption { return func(*routeOptions) {} } func WithSSE() RouteOption { return func(*routeOptions) {} } func WithMaxBytes(_ int64) RouteOption { return func(*routeOptions) {} } func WithTimeout(_ any) RouteOption { return func(*routeOptions) {} } func (s *Server) AddRoutes(routes []Route, opts ...RouteOption) { options := routeOptions{} for _, opt := range opts { opt(&options) } for _, route := range routes { s.router.Handle(route.Method, joinPath(options.prefix, route.Path), chain(options.middleware, route.Handler)) } } func chain(middlewares []Middleware, handler gin.HandlerFunc) gin.HandlerFunc { if len(middlewares) == 0 { return handler } return func(c *gin.Context) { for _, middleware := range middlewares { middleware(c) if c.IsAborted() { return } } handler(c) } } func joinPath(prefix, routePath string) string { if prefix == "" { return routePath } joined := path.Join("/", prefix, routePath) if strings.HasSuffix(routePath, "/") && !strings.HasSuffix(joined, "/") { joined += "/" } return joined } var ( _ http.Handler )