router

package module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: MIT Imports: 29 Imported by: 0

README

NLG HTTP Router

A fast and idiomatic HTTP router for modern Go applications.

Use router to build APIs, web services, and backend applications with radix-tree routing, middleware, route groups, request context, static assets, rate limiting, profiling, and multi-server support.

Go Reference Go Report Card Go Version License


About

router is a production-oriented HTTP routing package for Go focused on performance, composability, and clean application structure.

It combines radix-tree based route matching with middleware pipelines, hierarchical route grouping, request-scoped context utilities, recovery handling, rate limiting, profiling support, static asset serving, and multi-server orchestration.

The package is built on top of Go’s standard net/http interfaces and is designed for APIs, web services, microservices, backend platforms, and internal services.

Features

  • Fast Radix Router: Optimized radix-tree based route lookup for static, wildcard, mounted, and parameterized routes
  • Parameterized Routes: Supports route parameters such as /users/{id}
  • Prepared Pattern Matching: Built-in matchers for UUIDs, digits, slugs, dates, hex values, base64 values, and safe path segments
  • Regex Route Parameters: Define custom route parameters with regular expressions
  • Route Groups: Organize routes using hierarchical groups with inherited middleware
  • Middleware Pipeline: Compose global, grouped, and route-level middleware
  • Mount Support: Mount existing http.Handler and http.HandlerFunc implementations under route prefixes
  • Pooled Request Context: Per-request context with parameter access and temporary key/value storage
  • Health Check Endpoints: Built-in liveness and readiness route helpers
  • Rate Limiting Guard: Built-in middleware for request throttling and cooldown-based protection
  • Built-in pprof Profiling: Enable a dedicated profiling server with Go’s standard net/http/pprof
  • Static File Serving: Serve static directories with automatic favicon.ico support
  • Custom NotFound Handler: Override the default 404 page not found response
  • Custom Recovery Handler: Recover from panics and provide your own fallback response
  • Panic Logging: Panic details are logged through Go’s standard log/slog
  • Access Logging: Optional middleware for structured request logging
  • Multi-Server Support: Run multiple listeners from a single router
  • Graceful Shutdown: Handles interrupt and termination signals with safe HTTP server shutdown
  • Standard Library Compatible: Works with net/http, http.Handler, http.HandlerFunc, and log/slog

Requirements

This package requires Go 1.25 or newer.

  • Go: 1.25 or newer
  • Dependencies: Standard library + github.com/netlifeguru/logger

Installation

Add the package to your project using go get:

go get github.com/netlifeguru/router@v0.1.0

Quick Start

package main

import (
	"log/slog"
	"net/http"
	"os"

	"github.com/netlifeguru/logger"
	"github.com/netlifeguru/router"
)

func main() {
	r := router.New()

	closer, err := logger.Init(logger.Config{
		Dir:             "./logs",
		TerminalOutput:  true,
		DisableColors:   false,
		MinLevel:        slog.LevelInfo,
		ConsoleMinLevel: slog.LevelDebug,
		MaxFileSize:     100 * 1024 * 1024,
		MaxLogFiles:     10,
	})
	if err != nil {
		slog.Error("failed to initialize logger", "error", err)
		os.Exit(1)
	}

	defer func() {
		if err := closer.Close(); err != nil {
			slog.Error("failed to close logger", "error", err)
		}
	}()

	r.Use(router.Logger())

	r.HandleFunc("/", "GET POST", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		w.Header().Set("Content-Type", "text/html")
		w.WriteHeader(http.StatusCreated)
		_, _ = w.Write([]byte(`<h1>Hello World</h1>`))
	})

	r.HandleFunc("/user/{id}", "GET", func(w http.ResponseWriter, req *http.Request, ctx *router.Context) {
		id := ctx.Param("id")
		_, _ = w.Write([]byte(id))
	})

	if err := r.ListenAndServe(":8000"); err != nil {
		slog.Error("failed to start server", "error", err)
		os.Exit(1)
	}
}

Run the application:

go run main.go

Example requests:

curl http://localhost:8000/
curl http://localhost:8000/user/42

Expected response:

42

Examples

Practical examples are available in the official examples repository:

https://github.com/netlifeguru/examples/router

Example categories include:

  • default router setup
  • handlers
  • middleware
  • route groups
  • mounting handlers
  • custom route patterns
  • static file serving
  • health check endpoints
  • request logging
  • recovery middleware
  • custom error handling
  • rate limiting
  • built-in profiling
  • multi-server setup
  • observability integrations

Documentation

Full package documentation, guides, and examples are available at:

https://netlife.guru/docs/go/router

API reference is also available on pkg.go.dev:

https://pkg.go.dev/github.com/netlifeguru/router


Notes

  • Review package-specific concurrency behavior before using it in highly parallel workloads.
  • Check performance characteristics when using this package in latency-sensitive paths.
  • Observability examples may require additional third-party packages and external tooling.
  • See the package documentation and examples for limitations and recommended usage patterns.

Versioning

This project follows Semantic Versioning.

See CHANGELOG.md for release history and breaking changes.


Contributing

Community contributions, feedback, and improvements are welcome.

Please read CONTRIBUTING.md before submitting pull requests or opening issues.


Code of Conduct

This project follows a Code of Conduct.

Please read CODE_OF_CONDUCT.md before contributing or participating in discussions.


Author

Created and maintained by NetLife Guru s.r.o.


License

MIT License. See LICENSE.

Documentation

Index

Constants

View Source
const (
	GET     = 1 << 0
	POST    = 1 << 1
	PUT     = 1 << 2
	DELETE  = 1 << 3
	PATCH   = 1 << 4
	HEAD    = 1 << 5
	OPTIONS = 1 << 6
	CONNECT = 1 << 7
	TRACE   = 1 << 8
	ANY     = 1 << 9
)

Variables

View Source
var (
	// ErrInvalidListenAddress indicates that a listen address is malformed
	// or cannot be split into host and port.
	ErrInvalidListenAddress = errors.New("router: invalid listen address")

	// ErrInvalidListenPort indicates that the port part of a listen address
	// is not a valid numeric port.
	ErrInvalidListenPort = errors.New("router: invalid listen port")

	// ErrListenFailed indicates that the router failed to bind a TCP listener.
	ErrListenFailed = errors.New("router: listen failed")

	// ErrServeFailed indicates that http.Server.Serve returned an unexpected error.
	ErrServeFailed = errors.New("router: serve failed")

	// ErrHijackerNotSupported indicates that the wrapped ResponseWriter
	// does not implement http.Hijacker.
	ErrHijackerNotSupported = errors.New("router: hijacker not supported")

	// ErrInvalidTrustedProxyCIDR indicates that a trusted proxy CIDR is invalid.
	ErrInvalidTrustedProxyCIDR = errors.New("router: invalid trusted proxy CIDR")
)

Functions

func ClientIP

func ClientIP(r *http.Request) string

func RequestIDFromContext

func RequestIDFromContext(ctx context.Context) string

func SetTrustedProxies

func SetTrustedProxies(cidrs []string) error

Types

type CORSOptions

type CORSOptions struct {
	AllowedOrigins   []string
	AllowedMethods   []string
	AllowedHeaders   []string
	ExposedHeaders   []string
	AllowCredentials bool
	MaxAge           int
}

type Context

type Context struct {
	// contains filtered or unexported fields
}

func (*Context) Get

func (c *Context) Get(key string) any

func (*Context) Param

func (c *Context) Param(key string) string

func (*Context) Set

func (c *Context) Set(key string, value any)

type HandlerFunc

type HandlerFunc func(http.ResponseWriter, *http.Request, *Context)

type Listener

type Listener struct {
	Addr string
}

type Listeners

type Listeners []Listener

type Middleware

type Middleware func(HandlerFunc) HandlerFunc

func AllowContentType

func AllowContentType(types ...string) Middleware

func CORS

func CORS(opts CORSOptions) Middleware

func CleanPath

func CleanPath() Middleware

CleanPath normalizes r.URL.Path after the route has already matched. If you need cleaning before route matching, do it in Router.ServeHTTP before lookup.

func Compress

func Compress(level int, types ...string) Middleware

func ContentCharset

func ContentCharset(charsets ...string) Middleware

func DefaultCompress

func DefaultCompress() Middleware

func GetHead

func GetHead() Middleware

func Logger

func Logger() Middleware

func NoCache

func NoCache() Middleware

func RateLimit

func RateLimit(threshold time.Duration, opts ...RateLimitOption) Middleware

func RealIP

func RealIP() Middleware

func RequestID

func RequestID() Middleware

func RequestIDWithGenerator

func RequestIDWithGenerator(generate func(*http.Request) string) Middleware

type RateLimitConfig

type RateLimitConfig struct {
	KeyFn           func(r *http.Request, c *Context) string
	OnLimit         func(w http.ResponseWriter, r *http.Request, c *Context, retryAfter time.Duration)
	TTL             time.Duration
	CleanupInterval time.Duration
}

type RateLimitOption

type RateLimitOption func(*RateLimitConfig)

type RouteGroup

type RouteGroup struct {
	// contains filtered or unexported fields
}

func (*RouteGroup) CONNECT

func (g *RouteGroup) CONNECT(url string, fn HandlerFunc)

func (*RouteGroup) DELETE

func (g *RouteGroup) DELETE(url string, fn HandlerFunc)

func (*RouteGroup) GET

func (g *RouteGroup) GET(url string, fn HandlerFunc)

func (*RouteGroup) HEAD

func (g *RouteGroup) HEAD(url string, fn HandlerFunc)

func (*RouteGroup) HandleFunc

func (g *RouteGroup) HandleFunc(url string, methods string, fn HandlerFunc)

func (*RouteGroup) Mount

func (g *RouteGroup) Mount(prefix string, handler http.Handler)

func (*RouteGroup) MountFunc

func (g *RouteGroup) MountFunc(prefix string, fn func(w http.ResponseWriter, req *http.Request))

func (*RouteGroup) OPTIONS

func (g *RouteGroup) OPTIONS(url string, fn HandlerFunc)

func (*RouteGroup) PATCH

func (g *RouteGroup) PATCH(url string, fn HandlerFunc)

func (*RouteGroup) POST

func (g *RouteGroup) POST(url string, fn HandlerFunc)

func (*RouteGroup) PUT

func (g *RouteGroup) PUT(url string, fn HandlerFunc)

func (*RouteGroup) TRACE

func (g *RouteGroup) TRACE(url string, fn HandlerFunc)

func (*RouteGroup) Use

func (g *RouteGroup) Use(m Middleware)

type Router

type Router struct {
	// contains filtered or unexported fields
}

func New

func New() *Router

func (*Router) CONNECT

func (r *Router) CONNECT(url string, fn HandlerFunc)

func (*Router) DELETE

func (r *Router) DELETE(url string, fn HandlerFunc)

func (*Router) EnableProfiling

func (r *Router) EnableProfiling(profilingServer string)

func (*Router) GET

func (r *Router) GET(url string, fn HandlerFunc)

func (*Router) Group

func (r *Router) Group(prefix string) *RouteGroup

func (*Router) HEAD

func (r *Router) HEAD(url string, fn HandlerFunc)

func (*Router) HandleFunc

func (r *Router) HandleFunc(url string, methods string, fn HandlerFunc)

func (*Router) IsReady

func (r *Router) IsReady() bool

func (*Router) ListenAndServe

func (r *Router) ListenAndServe(addr string) error

func (*Router) Liveness

func (r *Router) Liveness(path string, fn func(w http.ResponseWriter, req *http.Request))

func (*Router) Mount

func (r *Router) Mount(path string, handler http.Handler)

func (*Router) MountFunc

func (r *Router) MountFunc(prefix string, fn func(w http.ResponseWriter, req *http.Request))

func (*Router) MultiListenAndServe

func (r *Router) MultiListenAndServe(listeners Listeners) error

func (*Router) NotFound

func (r *Router) NotFound(fn HandlerFunc)

func (*Router) OPTIONS

func (r *Router) OPTIONS(url string, fn HandlerFunc)

func (*Router) PATCH

func (r *Router) PATCH(url string, fn HandlerFunc)

func (*Router) POST

func (r *Router) POST(url string, fn HandlerFunc)

func (*Router) PUT

func (r *Router) PUT(url string, fn HandlerFunc)

func (*Router) Readiness

func (r *Router) Readiness(path string, fn func(w http.ResponseWriter, req *http.Request))

func (*Router) Recovery

func (r *Router) Recovery(fn HandlerFunc)

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Router) SetReady

func (r *Router) SetReady(ready bool)

func (*Router) Static

func (r *Router) Static(urlPrefix string, rootPath string)

func (*Router) TRACE

func (r *Router) TRACE(url string, fn HandlerFunc)

func (*Router) Use

func (r *Router) Use(m Middleware)

func (*Router) UseDefaults

func (r *Router) UseDefaults()

func (*Router) With

func (r *Router) With(middlewares ...Middleware) *middlewareGroup

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL