add routes groups and middlewares capabilities
This commit is contained in:
@@ -24,10 +24,27 @@ type (
|
||||
E *Engine
|
||||
}
|
||||
|
||||
router struct {
|
||||
path string
|
||||
method string
|
||||
handler func(*Context)
|
||||
group *routerGroup
|
||||
}
|
||||
|
||||
routerGroup struct {
|
||||
prefix string
|
||||
middlewares middlewareChain
|
||||
engine *Engine
|
||||
}
|
||||
|
||||
middlewareChain []func(http.Handler) http.Handler
|
||||
|
||||
Engine struct {
|
||||
mux *http.ServeMux
|
||||
LogLevel slog.Level
|
||||
Render *Render
|
||||
LogLevel slog.Level
|
||||
Render *Render
|
||||
mux *http.ServeMux
|
||||
middlewares middlewareChain
|
||||
router []router
|
||||
}
|
||||
)
|
||||
|
||||
@@ -53,8 +70,32 @@ func (e *Engine) apply(opts ...EngineOptions) *Engine {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *Engine) applyMiddlewares(handler http.Handler) http.Handler {
|
||||
for i := len(e.middlewares) - 1; i >= 0; i-- {
|
||||
handler = e.middlewares[i](handler)
|
||||
}
|
||||
return handler
|
||||
}
|
||||
|
||||
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
e.handleRequest(w, r)
|
||||
handler := e.applyMiddlewares(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
for _, route := range e.router {
|
||||
if strings.HasPrefix(r.URL.Path, route.path) && r.Method == route.method {
|
||||
groupHandler := http.Handler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
route.handler(&Context{W: w, R: r, E: e})
|
||||
}))
|
||||
if route.group != nil {
|
||||
for i := len(route.group.middlewares) - 1; i >= 0; i-- {
|
||||
groupHandler = route.group.middlewares[i](groupHandler)
|
||||
}
|
||||
}
|
||||
groupHandler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
http.NotFound(w, r)
|
||||
}))
|
||||
handler.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (e *Engine) Run(addr string) error {
|
||||
@@ -66,24 +107,35 @@ func (e *Engine) handleRequest(w http.ResponseWriter, r *http.Request) {
|
||||
e.mux.ServeHTTP(w, r)
|
||||
}
|
||||
|
||||
func (e *Engine) USE(middleware ...func(http.Handler) http.Handler) {
|
||||
e.middlewares = append(e.middlewares, middleware...)
|
||||
}
|
||||
|
||||
func (e *Engine) GET(path string, handler func(*Context)) {
|
||||
e.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
handler(&Context{W: w, R: r, E: e})
|
||||
})
|
||||
e.router = append(e.router, router{path: path, method: http.MethodGet, handler: handler})
|
||||
}
|
||||
|
||||
func (e *Engine) POST(path string, handler func(*Context)) {
|
||||
e.mux.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
http.Error(w, "Method Not Allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
handler(&Context{W: w, R: r, E: e})
|
||||
})
|
||||
e.router = append(e.router, router{path: path, method: http.MethodPost, handler: handler})
|
||||
}
|
||||
|
||||
func (e *Engine) GROUP(prefix string) *routerGroup {
|
||||
return &routerGroup{
|
||||
prefix: prefix,
|
||||
engine: e,
|
||||
}
|
||||
}
|
||||
|
||||
func (rg *routerGroup) USE(middleware ...func(http.Handler) http.Handler) {
|
||||
rg.middlewares = append(rg.middlewares, middleware...)
|
||||
}
|
||||
|
||||
func (rg *routerGroup) GET(path string, handler func(*Context)) {
|
||||
rg.engine.router = append(rg.engine.router, router{path: rg.prefix + path, method: http.MethodGet, handler: handler, group: rg})
|
||||
}
|
||||
|
||||
func (rg *routerGroup) POST(path string, handler func(*Context)) {
|
||||
rg.engine.router = append(rg.engine.router, router{path: rg.prefix + path, method: http.MethodPost, handler: handler, group: rg})
|
||||
}
|
||||
|
||||
// Static serves static files from a specified directory, accessible through a defined URL path.
|
||||
@@ -107,7 +159,9 @@ func (e *Engine) Static(path, dir string) {
|
||||
}
|
||||
|
||||
fs := http.FileServer(http.Dir(dir))
|
||||
e.mux.Handle(path, http.StripPrefix(path, fs))
|
||||
e.GET(path, func(c *Context) {
|
||||
http.StripPrefix(path, fs).ServeHTTP(c.W, c.R)
|
||||
})
|
||||
slog.Info("Static files served", "path", path, "dir", dir)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user