Files
sux/README.md
2025-11-25 18:27:01 +01:00

2.5 KiB

sux

An allocation-conscious, middleware-capable HTTP router for Go with support for static routes, parameters (:id), wildcards (*path), route groups, and configurable 404/405 handling.

Installation

go get code.icod.de/dalu/sux

Quick start

package main

import (
	"net/http"

	"code.icod.de/dalu/sux"
)

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

	r.GET("/", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello"))
	})

	r.GET("/users/:id", func(w http.ResponseWriter, r *http.Request) {
		params := sux.ParamsFromContext(r)
		w.Write([]byte("user " + params.Get("id")))
	})

	http.ListenAndServe(":8080", r)
}

Middleware

Middleware wraps handlers and can be applied globally or per route group.

logger := func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// log request here
		next.ServeHTTP(w, r)
	})
}

r := sux.New()
r.Use(logger) // global

r.GET("/ping", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("pong"))
})

Route groups

Groups share a prefix and middleware.

api := r.Group("/api", func(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("X-API-Version", "v1")
		next.ServeHTTP(w, r)
	})
})

api.GET("/users", func(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("users"))
})

Parameters and wildcards

r.GET("/posts/:postId", func(w http.ResponseWriter, r *http.Request) {
	p := sux.ParamsFromContext(r)
	w.Write([]byte(p.Get("postId")))
})

r.GET("/files/*path", func(w http.ResponseWriter, r *http.Request) {
	p := sux.ParamsFromContext(r)
	w.Write([]byte("file: " + p.Get("path")))
})

404/405 handlers

r.NotFound(func(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "custom 404", http.StatusNotFound)
})

r.MethodNotAllowed(func(w http.ResponseWriter, r *http.Request) {
	http.Error(w, "custom 405", http.StatusMethodNotAllowed)
})

// Disable cross-method probing if you prefer 404s instead of 405 checks
r.EnableMethodNotAllowedCheck(false)

Performance notes

  • Internally pools parsed segments and parameter storage to reduce per-request allocations.
  • Parameters are copied into the request context so they remain valid even after handlers return (important for async users of the context).
  • For raw numbers, run go test -bench . -benchmem.

Testing

go test ./...

Benchmarks:

go test -bench . -benchmem