simpleroute

package module
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Sep 16, 2026 License: MIT Imports: 18 Imported by: 0

README

simpleroute

CI Go Reference Go Report Card

Lightweight, zero-dependency HTTP router for Go 1.24+.

Documentation →

Features

  • Zero external dependencies — pure stdlib
  • Path parameters{param} patterns injected into request context
  • Wildcard/catch-all parameters{param...} captures the remainder of the path, slashes included
  • Group routing — namespaced routes with shared middleware, nestable to any depth
  • Middleware chain — global, group, and route-level middleware
  • Polymorphic Use — accepts HttpRouter, http.Handler, MiddlewareFunc, method/pattern strings
  • Static file serving — supports both embed.FS and os.DirFS
  • Built-in middleware — CORS, panic recovery, request logging, request ID, gzip, rate limiter (global or per-key), body size limit, metrics, context injection
  • HEAD auto-routing — HEAD requests fall back to GET handlers, body stripped automatically
  • Custom 404/405 handlers — plug your own handlers via RouterConfig
  • Subtree mountrouter.Mount("/prefix", subHandler) for all methods
  • Query helpersQuery, QueryInt, QueryFloat, QueryBool with defaults
  • Response helpersJSON, BindJSON, WriteError, Text
  • Route introspectionrouter.Routes() lists every registered route for debugging/startup logging
  • Concurrent-safesync.Once build, no per-request locks, per-router logger
  • Production-ready server — configurable timeouts (10s read, 10s write, 60s idle by default)

Installation

go get github.com/hrydi/simpleroute

Requires Go 1.24.4+.

Quick Start

package main

import (
	"fmt"
	"net/http"

	"github.com/hrydi/simpleroute"
)

func main() {
	router := simpleroute.NewRouter(simpleroute.RouterConfig{})

	router.Get("/hello", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprint(w, "Hello, World!")
	}))

	if err := router.Build(); err != nil {
		panic(err)
	}

	server := simpleroute.NewHttp(simpleroute.ServerConfig{Addr: ":8080"})
	if err := server.Start(router); err != nil {
		panic(err)
	}
}

API

Router

args ...any accepts: http.Handler, MiddlewareFunc, []MiddlewareFunc (in any order).

Method Description
Get(path, args...) Register GET handler
Post(path, args...) Register POST handler
Put(path, args...) Register PUT handler
Patch(path, args...) Register PATCH handler
Delete(path, args...) Register DELETE handler
Head(path, args...) Register HEAD handler
Logger() Return the router's Logger instance
RouteRegister
Method Args types Description
Group(path, callback, args...) func(Router) Router, MiddlewareFunc, []MiddlewareFunc Namespaced route group
Use(args...) HttpRouter, string (method/pattern), http.Handler, MiddlewareFunc, []MiddlewareFunc Register middleware, handlers, or routes
Mount(path, handler) Register subtree handler for all HTTP methods
Middleware
Function Description
CORS(config) Configurable CORS with preflight
RecoverMiddleware(handler, stackTrace...) Panic recovery (returns 500), optional stack trace
ContentTypeJson(handler) Sets Content-Type: application/json
RequestLogger(handler, logger...) Logs method, path, and duration. Optional custom logger.
WithContext(key, val)(handler) Injects value into request context
RequestID(handler) Injects/preserves X-Request-ID header + context
Gzip(handler) Transparent gzip compression
RateLimiter(config) Token bucket rate limiter (returns 429). Global bucket by default, or per-key via RateLimiterConfig.KeyFunc (e.g. RemoteIP)
MaxBodyBytes(limit)(handler) Caps the request body at limit bytes via http.MaxBytesReader; handlers must check the read/decode error
Metrics(recorder) Atomic counters for total/active requests and cumulative duration
Utilities
Function Description
Params(r) map[string]string Extract path parameters from context as a map
URLParam(r, key) string Extract a single path parameter by name (zero-alloc)
JSON(w, code, data) Write JSON response with content-type
BindJSON(r, &dst) error Decode the request body as JSON into dst
WriteError(w, code, msg) Write plain-text error response
Text(w, code, msg) Write plain-text response
Handle(middlewares, handler) Build middleware chain
SetCtx(r, key, val) *http.Request Store value in request context (chainable)
GetCtx[T](r, key) (T, bool) Retrieve typed value from request context
Query(r, key) Get query parameter value
QueryInt(r, key, default) Get query parameter as int
QueryFloat(r, key, default) Get query parameter as float64
QueryBool(r, key, default) Get query parameter as bool
router.Routes() []RouteInfo List every registered route (method, pattern, middleware count); valid after Build()
Server
Type Description
ServerConfig Config with Addr, ReadTimeout, WriteTimeout, IdleTimeout
NewHttp(config) Create HTTP server with production-ready defaults
server.Start(router) Start serving (returns error, filters ErrServerClosed)
server.Stop(ctx) Graceful shutdown

Context

Base context

Set a parent context for all requests via RouterConfig:

ctx, cancel := context.WithCancel(context.Background())

r := simpleroute.NewRouter(simpleroute.RouterConfig{
    BaseContext: ctx,  // cancel ctx → all in-flight requests cancelled
})
Request-scoped values
func handler(w http.ResponseWriter, r *http.Request) {
    r = simpleroute.SetCtx(r, "user", user)
    // ... later or in middleware:
    user, ok := simpleroute.GetCtx[*User](r, "user")
}

SetCtx is chainable:

r = simpleroute.SetCtx(simpleroute.SetCtx(r, "a", 1), "b", 2)
Path parameters
id := simpleroute.Params(r)["id"]

Pluggable Logger

Set the logger once via RouterConfig — it applies to both router internals and custom middleware:

r := simpleroute.NewRouter(simpleroute.RouterConfig{
    Logger:   myLogger{},
    LogLevel: simpleroute.LogLevelDebug,
})

Levels: LogLevelErrorLogLevelWarnLogLevelInfo (default) → LogLevelDebug.

Access the logger from any code that holds a Router:

router.Logger().Infof("handling request")

The RequestLogger middleware accepts an optional logger parameter:

router.Use(simpleroute.RequestLogger(handler, myLogger))
Interface
type Logger interface {
    Errorf(format string, args ...any)
    Warnf(format string, args ...any)
    Infof(format string, args ...any)
    Debugf(format string, args ...any)
}
Example with zerolog
type zeroLogger struct {
    l zerolog.Logger
}

func (z *zeroLogger) Errorf(format string, args ...any) { z.l.Error().Msgf(format, args...) }
func (z *zeroLogger) Warnf(format string, args ...any)  { z.l.Warn().Msgf(format, args...) }
func (z *zeroLogger) Infof(format string, args ...any)  { z.l.Info().Msgf(format, args...) }
func (z *zeroLogger) Debugf(format string, args ...any) { z.l.Debug().Msgf(format, args...) }

Defaults to [simpleroute] [INFO/ERROR/...] prefixed output via log.Printf.

Path Parameters

Use {name} in route patterns:

router.Get("/user/{id}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    id := simpleroute.Params(r)["id"]
    fmt.Fprintf(w, "User: %s", id)
}))

Use {name...} as the last segment to capture the rest of the path (slashes included) — handy for file servers or proxies:

router.Get("/files/{path...}", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    path := simpleroute.URLParam(r, "path")
    fmt.Fprintf(w, "serving: %s", path)
}))

// GET /files/a/b/c.txt -> path = "a/b/c.txt"

A more specific route registered alongside a wildcard still wins for matching requests.

Route Groups

Group routes under a common prefix with optional shared middleware:

router.Group("/api", func(router simpleroute.Router) simpleroute.Router {
    router.Logger().Infof("setting up /api routes")
    return router.
        Get("/users", listUsers).
        Post("/users", createUser)
}, authMiddleware, loggerMiddleware)

Groups nest to any depth. The callback receives a Router (no Group/Use method), so cast to RouteRegister to nest:

router.Group("/api", func(router simpleroute.Router) simpleroute.Router {
    router.(simpleroute.RouteRegister).Group("/v1", func(v1 simpleroute.Router) simpleroute.Router {
        return v1.Get("/users", listUsers)
    }, v1OnlyMiddleware)
    return router
}, apiMiddleware)

// GET /api/v1/users runs: apiMiddleware -> v1OnlyMiddleware -> listUsers

Path prefixes concatenate (/api + /v1 + /users) and middleware chains outward-in (root → each group, outermost first → route).

Middleware Order

Global router middlewares → group middlewares → route middlewares → handler.

The first middleware in the chain wraps the outermost layer:

router.Use(requestLogger)          // outermost
router.Get("/data", handler, auth) // auth wraps handler
// Order: requestLogger → auth → handler

RecoverMiddleware

Panic recovery with optional stack trace:

// Default (no stack trace)
router.Use("/api", apiHandler, simpleroute.RecoverMiddleware)

// With stack trace logged at ERROR level
router.Use("/api", apiHandler, simpleroute.RecoverMiddleware)

RecoverMiddleware is automatically applied to all requests by NewHttp/server.Start(). Only use it explicitly if you need a custom panic boundary.

CORS Example

router.Use("/api", apiHandler, simpleroute.CORS(simpleroute.CORSConfig{
    AllowedOrigins:   []string{"https://example.com"},
    AllowedMethods:   []string{"GET", "POST"},
    AllowedHeaders:   []string{"Content-Type"},
    AllowCredentials: true,
    MaxAge:           3600,
}))

Rate Limiter

Token bucket rate limiter. By default all requests share a single global bucket:

router.Use("/api", simpleroute.RateLimiter(simpleroute.RateLimiterConfig{
    RequestsPerSecond: 10,
    Burst:             20,
}))

Pass KeyFunc for per-client limiting — one bucket per key, with idle buckets evicted automatically:

router.Use("/api", simpleroute.RateLimiter(simpleroute.RateLimiterConfig{
    RequestsPerSecond: 10,
    Burst:             20,
    KeyFunc:           simpleroute.RemoteIP, // or e.g. func(r *http.Request) string { return r.Header.Get("X-API-Key") }
}))

Request Body Binding & Limits

Decode a JSON body:

router.Post("/users", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    var in CreateUserRequest
    if err := simpleroute.BindJSON(r, &in); err != nil {
        simpleroute.WriteError(w, http.StatusBadRequest, "invalid body")
        return
    }
    // ...
}))

Cap the request body size — combine with BindJSON for safe JSON APIs:

router.Post("/upload", uploadHandler, simpleroute.MaxBodyBytes(1<<20)) // 1MB

MaxBodyBytes wraps r.Body with http.MaxBytesReader; the limit is enforced when the body is read, so the handler (or BindJSON) must check the error and respond with http.StatusRequestEntityTooLarge itself.

Route Introspection

List every registered route after Build() — useful for logging all endpoints at startup:

if err := router.Build(); err != nil {
    log.Fatal(err)
}
for _, rt := range router.Routes() {
    fmt.Printf("%-6s %s (%d middleware)\n", rt.Method, rt.Pattern, rt.Middlewares)
}

Metrics

Atomic request metrics collector:

metrics := &simpleroute.MetricsRecorder{}
router.Use(simpleroute.Metrics(metrics))
go func() {
    for range time.Tick(10 * time.Second) {
        snap := metrics.Snapshot()
        fmt.Printf("requests: %d, active: %d, avg_dur: %dns\n",
            snap["total_requests"], snap["active_requests"], snap["avg_duration_ns"])
    }
}()

Subtree Mount

Mount an http.Handler as a subtree for all HTTP methods:

router.Mount("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./public"))))

Static Files

Serve embedded or on-disk static assets:

//go:embed static/*
var staticFS embed.FS

router := simpleroute.NewRouter(simpleroute.RouterConfig{
    AssetPath: "/assets/",
    AssetDir:  "static",
    FS:        staticFS,
})

Custom 404/405 Handlers

router := simpleroute.NewRouter(simpleroute.RouterConfig{
    NotFoundHandler:         http.HandlerFunc(custom404),
    MethodNotAllowedHandler: http.HandlerFunc(custom405),
})

HEAD Auto-Routing

HEAD requests automatically fall back to GET handlers when no explicit HEAD handler is registered. The response body is stripped — headers and status code are preserved:

router.Get("/data", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    w.Header().Set("Content-Length", "5")
    fmt.Fprint(w, "hello")
}))

// HEAD /data → 200, Content-Length: 5, body: ""

Built-in HTTP Server

server := simpleroute.NewHttp(simpleroute.ServerConfig{
    Addr: ":8080",
    // ReadTimeout, WriteTimeout, IdleTimeout default to 10s/10s/60s
})
go func() {
    if err := server.Start(router); err != nil {
        log.Fatal(err)
    }
}()
// ... later
server.Stop(ctx)  // graceful shutdown

Benchmarks

goos: linux
goarch: amd64
cpu: 11th Gen Intel(R) Core(TM) i5-1135G7 @ 2.40GHz
BenchmarkStaticRoute-8              10,124,955    127 ns/op    242 B/op     5 allocs/op
BenchmarkStaticRouteDeep-8           8,391,156    151 ns/op    240 B/op     5 allocs/op
BenchmarkPathParams-8                3,818,419    404 ns/op    776 B/op    12 allocs/op
BenchmarkNotFound-8                  2,643,332    589 ns/op   1234 B/op    21 allocs/op
BenchmarkCatchAll-8                  4,942,819    260 ns/op    288 B/op     8 allocs/op
BenchmarkMultipleRoutes-8            5,115,830    282 ns/op    240 B/op     5 allocs/op
BenchmarkBuild-8                           222  5.71 ms/op  4.48 MB/op    40k allocs/op
BenchmarkMiddlewareChainDepth-8      8,036,977    161 ns/op    240 B/op     5 allocs/op
BenchmarkParamsExtraction-8          3,903,521    423 ns/op   1016 B/op    12 allocs/op
BenchmarkGroupedRoutes-8             8,266,606    149 ns/op    240 B/op     5 allocs/op
BenchmarkRouteRegistration-8            28,312 36.3 μs/op 44.3 kB/op     513 allocs/op
BenchmarkConcurrentServe-8             730,724  1.73 μs/op 5.35 kB/op      14 allocs/op

Development

make run          # run example app (needs Vite running)
make compose-run  # full dev stack via Docker Compose
make build        # production Docker build

Run tests:

go test ./... -v
go test -race ./...
go test -bench=. -benchmem ./...

Documentation

Full docs are in docs/:

Page Description
Getting Started Install, quick start, lifecycle
Routing Methods, path params, groups, mount, static files, HEAD auto-routing, custom 404/405
Middleware Built-in middleware, custom middleware, ordering
Context & Logger Base context, SetCtx/GetCtx, Params, logger interface
Configuration RouterConfig, ServerConfig, polymorphic Use, benchmarks

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var METHODS = []string{
	"GET",
	"HEAD",
	"POST",
	"PUT",
	"DELETE",
	"PATCH",
	"OPTIONS",
}

METHODS lists all HTTP methods the router supports.

Functions

func BindJSON

func BindJSON(r *http.Request, dst any) error

BindJSON decodes the request body as JSON into dst. dst must be a pointer. The caller is responsible for translating a non-nil error into an HTTP response (e.g. http.StatusBadRequest, or http.StatusRequestEntityTooLarge if the body was wrapped with MaxBodyBytes).

func CORS

func CORS(config CORSConfig) func(http.Handler) http.Handler

CORS returns a middleware that handles cross-origin requests. Preflight (OPTIONS) requests return 204 without calling the next handler.

func ContentTypeJson

func ContentTypeJson(next http.Handler) http.Handler

ContentTypeJson sets Content-Type: application/json on every response.

func GetCtx

func GetCtx[T any](r *http.Request, key any) (T, bool)

GetCtx retrieves a typed value from the request context. Returns the zero value and false if the key is missing or the type doesn't match.

func Gzip

func Gzip(next http.Handler) http.Handler

Gzip returns a middleware that compresses responses with gzip when the client sends Accept-Encoding: gzip.

func Handle

func Handle(handlers []MiddlewareFunc, handler http.Handler) http.Handler

Handle builds a middleware chain around the given handler. Middleware order: the first middleware in the slice is the outermost wrapper. If handler is nil, a default http.NewServeMux is used as the base.

func JSON

func JSON(w http.ResponseWriter, code int, data any)

JSON writes data as JSON with the given status code. Sets Content-Type to application/json automatically.

func MaxBodyBytes

func MaxBodyBytes(limit int64) func(http.Handler) http.Handler

MaxBodyBytes returns a middleware that caps the request body at limit bytes using http.MaxBytesReader. The limit is enforced lazily as the body is read, so handlers (or BindJSON) must check the read/decode error and respond with http.StatusRequestEntityTooLarge themselves.

func Metrics

func Metrics(recorder *MetricsRecorder) func(http.Handler) http.Handler

Metrics returns a middleware that records request count, concurrency, and cumulative duration. Pass a shared *MetricsRecorder to collect data.

func NewHttp

func NewHttp(config ServerConfig) *httpServerImpl

NewHttp creates a new HTTP server for the given config. Production-ready timeouts are set by default (configurable via ServerConfig).

func NewRouter

func NewRouter(config RouterConfig) *routerImpl

NewRouter creates a new router with the given configuration.

func Params

func Params(r *http.Request) map[string]string

Params extracts all path parameters from the request context as a map. Returns nil if no parameters were matched.

func Query

func Query(r *http.Request, key string) string

Query returns the first value of the named query parameter, or empty string.

func QueryBool

func QueryBool(r *http.Request, key string, defaultVal bool) bool

QueryBool returns the first value of the named query parameter as bool. Accepts "1", "t", "T", "true", "TRUE", "True" as true. Returns the default value if the parameter is missing.

func QueryFloat

func QueryFloat(r *http.Request, key string, defaultVal float64) float64

QueryFloat returns the first value of the named query parameter as float64, or the default value if the parameter is missing or not a valid number.

func QueryInt

func QueryInt(r *http.Request, key string, defaultVal int) int

QueryInt returns the first value of the named query parameter as int, or the default value if the parameter is missing or not a valid integer.

func RateLimiter

func RateLimiter(config RateLimiterConfig) func(http.Handler) http.Handler

RateLimiter returns a middleware that limits request rates using a token bucket algorithm, one bucket per KeyFunc(r) (or a single shared bucket if KeyFunc is nil). It returns 429 Too Many Requests when a bucket is empty.

func RecoverMiddleware

func RecoverMiddleware(next http.Handler, stackTrace ...bool) http.Handler

RecoverMiddleware catches panics in the handler chain, logs the error, and returns a 500 Internal Server Error to the client. When stackTrace is true, the full stack trace is logged at error level.

func RemoteIP

func RemoteIP(r *http.Request) string

RemoteIP is a RateLimiterConfig.KeyFunc that keys by the request's remote IP address, with the port stripped. Falls back to the raw RemoteAddr if it cannot be parsed as host:port (e.g. in tests that set it directly).

func RequestID

func RequestID(next http.Handler) http.Handler

RequestID injects or preserves an X-Request-ID header in both the response and the request context. If the incoming request has no X-Request-ID, a unique ID is generated using the current timestamp.

func RequestLogger

func RequestLogger(next http.Handler, logger ...Logger) http.Handler

RequestLogger logs the HTTP method, path, and duration of each request. An optional logger can be provided; otherwise uses standard log output.

func SetCtx

func SetCtx(r *http.Request, key, value any) *http.Request

SetCtx stores a value in the request context and returns the modified request. Chainable: r = SetCtx(SetCtx(r, "a", 1), "b", 2).

func Text

func Text(w http.ResponseWriter, code int, msg string)

Text writes a plain-text response with the given status code.

func URLParam

func URLParam(r *http.Request, key string) string

URLParam returns the value of a single path parameter by name. Returns empty string if the parameter is not found.

func WriteError

func WriteError(w http.ResponseWriter, code int, msg string)

WriteError writes a plain-text error response with the given status code.

Types

type CORSConfig

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

CORSConfig configures CORS behavior for the CORS middleware.

type ContextKey

type ContextKey string

ContextKey is used for request context value keys.

const ParamsContextKey ContextKey = "route_params"

ParamsContextKey is the context key for path parameters.

type HttpRouter

type HttpRouter interface {
	// Routes registers routes onto the given RouteRegister.
	Routes(r RouteRegister)
}

HttpRouter is implemented by types that register routes onto a RouteRegister. Use it to encapsulate route groups in separate types (see example/user.go).

type HttpServer

type HttpServer interface {
	Start(router http.Handler) error
	Stop(ctx context.Context) error
}

HttpServer wraps http.Server with graceful Start/Stop lifecycle.

type LogLevel

type LogLevel int

LogLevel represents the minimum level a log message must have to be emitted.

const (
	LogLevelError LogLevel = iota + 1
	LogLevelWarn
	LogLevelInfo
	LogLevelDebug
)

type Logger

type Logger interface {
	// Errorf logs a message at ERROR level.
	Errorf(format string, args ...any)
	// Warnf logs a message at WARN level.
	Warnf(format string, args ...any)
	// Infof logs a message at INFO level.
	Infof(format string, args ...any)
	// Debugf logs a message at DEBUG level.
	Debugf(format string, args ...any)
}

Logger is the interface for leveled logging in the router. Implementations should respect the receiver's own level filtering, or use the LogLevel from RouterConfig for filtering.

type MetricsRecorder

type MetricsRecorder struct {
	TotalRequests  atomic.Int64
	ActiveRequests atomic.Int64
	TotalDuration  atomic.Int64
}

MetricsRecorder records HTTP request metrics.

func (*MetricsRecorder) Snapshot

func (m *MetricsRecorder) Snapshot() map[string]any

Snapshot returns a point-in-time snapshot of the metrics.

type MiddlewareFunc

type MiddlewareFunc = func(http.Handler) http.Handler

MiddlewareFunc wraps an http.Handler to add cross-cutting behavior.

func WithContext

func WithContext(name string, value any) MiddlewareFunc

WithContext injects a key-value pair into the request context.

type Param

type Param struct {
	Key   string
	Value string
}

Param represents a single key-value path parameter.

type RateLimiterConfig

type RateLimiterConfig struct {
	RequestsPerSecond int
	Burst             int
	// KeyFunc extracts the rate-limit bucket key from a request, e.g. RemoteIP
	// for per-client limiting. If nil, all requests share a single global
	// bucket (pre-KeyFunc behavior).
	KeyFunc func(*http.Request) string
}

RateLimiterConfig configures the rate limiter middleware.

type RouteInfo

type RouteInfo struct {
	Method      string
	Pattern     string
	Middlewares int
}

RouteInfo describes a single registered route, as returned by Routes(). It is a diagnostic snapshot (e.g. for logging all endpoints at startup), not part of the request-handling path.

type RouteRegister

type RouteRegister interface {
	Router
	// Group creates a route group under path. args accepts:
	//   - func(Router) Router — the group callback
	//   - MiddlewareFunc, []MiddlewareFunc — group-level middleware
	Group(path string, args ...any) Router
	// Use registers middleware, handlers, or HttpRouter in a single call.
	// Types are identified by type and can be mixed in any order.
	Use(args ...any) RouteRegister
}

RouteRegister extends Router with group and middleware registration. Use accepts any combination of:

  • HttpRouter — calls Routes(r) to register routes
  • string — HTTP method or URL pattern
  • http.Handler — the route handler
  • MiddlewareFunc — middleware wrapping the handler
  • []MiddlewareFunc — multiple middleware

type Router

type Router interface {
	// Get registers a GET handler at the given path.
	Get(path string, args ...any) Router
	// Post registers a POST handler at the given path.
	Post(path string, args ...any) Router
	// Put registers a PUT handler at the given path.
	Put(path string, args ...any) Router
	// Patch registers a PATCH handler at the given path.
	Patch(path string, args ...any) Router
	// Delete registers a DELETE handler at the given path.
	Delete(path string, args ...any) Router
	// Head registers a HEAD handler at the given path.
	Head(path string, args ...any) Router
	// Mount attaches a sub-handler under the given path prefix for all HTTP methods.
	Mount(path string, sub http.Handler) Router
	// Logger returns the router's Logger instance.
	Logger() Logger
}

Router defines HTTP method handlers for route registration. Each method accepts args ...any which are identified by type:

  • http.Handler — the route handler
  • MiddlewareFunc — middleware wrapping the handler
  • []MiddlewareFunc — multiple middleware

They can appear in any order.

type RouterAction

type RouterAction = func(router Router) Router

RouterAction is a callback that receives a Router and returns it.

type RouterConfig

type RouterConfig struct {
	AssetDir                string
	AssetPath               string
	FS                      fs.FS
	Logger                  Logger
	LogLevel                LogLevel
	BaseContext             context.Context
	NotFoundHandler         http.Handler
	MethodNotAllowedHandler http.Handler
}

RouterConfig configures a new router instance.

type ServerConfig

type ServerConfig struct {
	Addr         string
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	IdleTimeout  time.Duration
}

ServerConfig configures the HTTP server created by NewHttp. Zero values are replaced with sensible production defaults (10s ReadTimeout, 10s WriteTimeout, 60s IdleTimeout).

Directories

Path Synopsis
ui
pkg

Jump to

Keyboard shortcuts

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