Mounting Standard Handlers
Mount native net/http handlers, third-party services, and wildcard routes directly into the router without using router.Context.
The router package supports mounting native Go net/http handlers directly into the routing tree.
This allows seamless integration with:
- third-party HTTP services
- legacy applications
- Prometheus metrics
- Swagger UI
- pprof
- static file servers
- external routers
- standard
net/httpmiddleware
Mounted handlers use the standard Go handler signature and do not require *router.Context.
Mount vs MountFunc
The router provides two mounting helpers:
| Method | Description |
|---|---|
Mount | Mounts a standard http.Handler |
MountFunc | Mounts a standard handler function |
Mount
Use Mount when working with a type implementing http.Handler.
r.Mount("/service", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Mounted standard service"))
}))This is useful for:
- external libraries
- reusable handlers
- middleware stacks
- mounted sub-services
MountFunc
MountFunc is a convenience wrapper around Mount.
r.MountFunc("/serviceFunc", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Mounted standard function")
})This avoids explicitly converting functions into http.HandlerFunc.
Example
package main
import (
"fmt"
"log/slog"
"net/http"
"os"
"github.com/netlifeguru/router"
)
func main() {
r := router.New()
r.Mount("/service", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Mounted standard service (http.Handler)"))
}))
r.MountFunc("/serviceFunc", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Mounted standard function")
})
r.Mount("/service/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
fmt.Fprintf(w, "Mounted service with ID: %s", id)
}))
r.MountFunc("/serviceFunc/{id}/abc", func(w http.ResponseWriter, r *http.Request) {
id := r.PathValue("id")
fmt.Fprintf(w, "Mounted func with ID: %s", id)
})
r.Mount("/services/*", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Wildcard captured path: %s", r.URL.Path)
}))
r.MountFunc("/servicesFunc/*", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Wildcard func captured path: %s", r.URL.Path)
})
if err := r.ListenAndServe(":8000"); err != nil {
slog.Error("failed to start server", "error", err)
os.Exit(1)
}
}Route Parameters
Mounted handlers still support route parameters.
Parameters can be accessed using Go’s native PathValue API:
id := r.PathValue("id")Example route:
r.Mount("/service/{id}", handler)Request:
/service/42Result:
42This keeps mounted handlers fully compatible with the router parameter system while preserving the standard net/http interface.
Wildcard Routes
Mounted handlers also support wildcard matching.
Example:
r.Mount("/services/*", handler)This captures all paths under:
/services/Example requests:
/services/api
/services/api/v1/users
/services/static/file.cssThis is useful for:
- mounting sub-routers
- SPA frontends
- reverse proxy handlers
- static file services
- external APIs
Interoperability
Mounted handlers make the router fully compatible with the broader Go net/http ecosystem.
This allows applications to combine router-native handlers:
func(w http.ResponseWriter, req *http.Request, ctx *router.Context)with standard Go handlers:
func(w http.ResponseWriter, req *http.Request)inside the same routing tree.
Common Integrations
Mounted handlers make it easy to integrate existing Go services and third-party libraries directly into the router.
Examples:
| Service | Example |
|---|---|
| Prometheus Metrics | r.Mount("/metrics", promhttp.Handler()) |
| GraphQL (gqlgen) | r.Mount("/graphql/query", srv) |
| GraphQL Playground | r.Mount("/graphql/playground", playground.Handler(...)) |
| pprof Profiling | r.Mount("/debug/pprof/", http.DefaultServeMux) |
| Swagger UI | r.Mount("/swagger/", swaggerHandler) |
| Static File Server | r.Mount("/public/", http.FileServer(...)) |
| Reverse Proxy | r.Mount("/api/", proxyHandler) |
| Legacy net/http Apps | r.Mount("/legacy/", legacyHandler) |
| WebSocket Services | r.Mount("/ws", websocketHandler) |
| Custom Admin Panels | r.Mount("/admin/", adminHandler) |
Example Prometheus integration:
import "github.com/prometheus/client_golang/prometheus/promhttp"
r.Mount("/metrics", promhttp.Handler())Example GraphQL integration using gqlgen:
g.Mount("/query", srv)
g.Mount("/playground", playground.Handler(...))This allows applications to combine router-native APIs with existing Go ecosystem tooling while keeping the routing layer unified.
Notes
Mounted handlers intentionally do not receive *router.Context.
This keeps them fully compatible with standard Go tooling and third-party libraries without requiring adapter layers or custom wrappers.