package router import ( "net/http" ) // HandlerFunc defines the signature of a handler function type HandlerFunc func(w http.ResponseWriter, r *http.Request) // Router struct holds all the routes, middlewares, and groups type Router struct { routes map[string]map[string]HandlerFunc middleware []HandlerFunc groups map[string]*Group } // NewRouter creates a new Router instance func NewRouter() *Router { return &Router{ routes: make(map[string]map[string]HandlerFunc), groups: make(map[string]*Group), } } // Use adds a global middleware to the router func (r *Router) Use(middleware HandlerFunc) { r.middleware = append(r.middleware, middleware) } // Handle registers a route with a method and a handler func (r *Router) Handle(method, path string, handler HandlerFunc) { if _, exists := r.routes[method]; !exists { r.routes[method] = make(map[string]HandlerFunc) } r.routes[method][path] = handler } // Group creates a new group with a prefix func (r *Router) Group(prefix string) *Group { group := &Group{ router: r, prefix: prefix, } r.groups[prefix] = group return group } // Group struct represents a group of routes with a common prefix type Group struct { router *Router prefix string middleware []HandlerFunc } // Use adds a middleware to a group func (g *Group) Use(middleware HandlerFunc) { g.middleware = append(g.middleware, middleware) } // Handle registers a route in the group func (g *Group) Handle(method, path string, handler HandlerFunc) { fullPath := g.prefix + path // Apply group middleware first for _, m := range g.middleware { g.router.Use(m) } // Register the route g.router.Handle(method, fullPath, handler) } // Get registers a GET route in the group func (g *Group) Get(path string, handler HandlerFunc) { g.Handle("GET", path, handler) } // Post registers a POST route in the group func (g *Group) Post(path string, handler HandlerFunc) { g.Handle("POST", path, handler) } // ServeHTTP is the main entry point for handling HTTP requests func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) { // Apply global middlewares for _, m := range r.middleware { m(w, req) } // Route matching if handlers, ok := r.routes[req.Method]; ok { if handler, ok := handlers[req.URL.Path]; ok { handler(w, req) return } } http.NotFound(w, req) }