Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

muxx

http.ServeMux gained method routing and path parameters in Go 1.22. What it still lacks is prefix grouping and middleware inheritance. muxx adds exactly those two things and nothing else.

Zero external dependencies. No magic. The underlying ServeMux is exposed through ServeHTTP — everything the stdlib provides works unchanged.


How it works

All groups share a single ServeMux. Groups are a registration-time concept only: they carry a prefix and a middleware chain that get applied when a route is registered. By the time a request arrives, the router is flat.

This means r.PathValue() works natively, there is no request rewriting, and there are no hidden layers to reason about.


Usage

r := muxx.New()

r.HandleFunc("GET /", homeHandler)

api := r.Group("/api")
api.Use(authMiddleware)

users := api.Group("/users")
users.HandleFunc("GET /", listUsers)
users.HandleFunc("POST /", createUser)
users.HandleFunc("GET /{id}", getUser)

http.ListenAndServe(":8080", r)

GET /users/{id} registers as GET /api/users/{id} in the underlying ServeMux. The authMiddleware runs on every route under /api.


Host-based routing

Group accepts the same pattern format as ServeMux. If the prefix does not start with /, it is treated as a host, matching ServeMux convention directly.

api := r.Group("api.example.com")
api.Use(authMiddleware)
api.HandleFunc("GET /users", listUsers)

Host and path can be combined in a single call:

admin := r.Group("admin.example.com/settings")
admin.HandleFunc("GET /profile", profileHandler)
// registers as: GET admin.example.com/settings/profile

Host groups compose with further Group calls and inherit middleware the same way path groups do.


Middleware

Middleware follows func(http.Handler) http.Handler. Apply it to a group with Use:

api.Use(authMiddleware, loggingMiddleware)

Child groups inherit the parent's middleware. Adding middleware to a child does not affect sibling groups or routes already registered.

Middleware runs in declaration order: the first argument is the outermost wrapper, closest to the request.

To compose middleware onto a single handler without a router, use Chain:

h := muxx.Chain(myHandler, authMiddleware, loggingMiddleware)

Wrapping an existing ServeMux

If you already have a *http.ServeMux, wrap it instead of creating a new one:

r := muxx.NewFromMux(existingMux)

API

New() *Router
NewFromMux(mux *http.ServeMux) *Router
(*Router).Group(prefix string) *Router
(*Router).Use(mw ...Middleware)
(*Router).Handle(pattern string, h http.Handler)
(*Router).HandleFunc(pattern string, fn http.HandlerFunc)
(*Router).ServeHTTP(w http.ResponseWriter, r *http.Request)
Chain(h http.Handler, m ...Middleware) http.Handler

Patterns follow the Go 1.22 ServeMux format: [METHOD ][HOST]PATH. Method, host, and path parameters work exactly as documented in net/http.

About

Route prefix grouping and middleware inheritance for go's http.ServeMux.

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages