kern

package module
v1.0.2 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 30 Imported by: 0

README

Kern - The Web Kernel for Go

kern logo

Go Reference Go Report Card CI Release

Kern is a lightweight web framework for Go focused on a small, reliable core so application code stays fast, explicit, and maintainable.

Why the name "kern"

"kern" comes from "kernel".

In operating systems, a kernel is the smallest trusted core that coordinates everything else. In the same spirit, Kern aims to be a small web kernel:

  • strong primitives
  • minimal policy
  • clean extension points
  • no unnecessary magic

The goal is not to be the biggest framework. The goal is to be a dependable core you can build on for years.

Motivation

Kern was created to reduce the gap between everyday HTTP work and the Go standard library. It is designed for teams that want a practical framework without hidden runtime complexity:

  • embraces net/http instead of hiding it
  • avoids dependency sprawl in the core runtime
  • stays explicit, testable, and easy to reason about
  • performs well without clever abstractions everywhere

The framework stays intentionally small so engineers can understand internals quickly, debug behavior confidently, and extend only what they need.

Inspiration

Kern is inspired by:

  • Go stdlib design: composable interfaces and explicit behavior
  • Flask (Python): minimal API surface with practical defaults
  • Javalin (Java/Kotlin): lightweight, no-reflection design with fluent routing
  • microkernel philosophy: small trusted core with optional modules around it

Features

  • Go 1.22+ native routing via http.ServeMux
  • Dual path parameter syntax — both :param and {param} styles are supported interchangeably
  • Named routes & path constraints — typed URL params (kern.UintPathConstraint) and route lookup by name
  • Built-in authBearerAuth and BasicAuth middleware ship in core
  • Route-specific middleware — apply guards per route with AddConstraints(), no group nesting needed
  • Structured request bindingBind() / BindQuery() / BindForm() / BindHeader() with struct tags
  • File handling — multipart upload (SaveFile), download (DownloadFile), streaming with range support (StreamFile)
  • Conditional requests — built-in ETag, LastModified, If-None-Match / If-Modified-Since evaluation
  • Built-in test clientkern.NewTestClient(app) for handler tests without a real HTTP server
  • Context pooling for lower allocation pressure
  • Middleware chaining with standard func(http.Handler) http.Handler
  • Route groups for shared prefixes and middleware
  • Graceful shutdown options for production servers
  • Zero core dependencies

Installation

go get github.com/mobentum/kern

Quality Baseline (Go)

Industry-style local checks for this repository:

# one-time tool install
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
go install golang.org/x/vuln/cmd/govulncheck@latest

# quality + tests
make go-quality
go test ./...

CI check order:

  1. go vet (correctness smells)
  2. golangci-lint (static lint suite)
  3. govulncheck (vulnerability scan)
  4. go build + go test

Test Status

Package Tests Build Coverage
kern (core) 107 81.5%
kern/middleware 55 82.5%
Total 162 ~82%

All tests pass with zero failures across both packages.

Quick Start

package main

import "github.com/mobentum/kern"

func main() {
    app := kern.Default()

    app.GET("/", func(c *kern.Context) {
        c.JSON(200, map[string]string{"message": "hello from kern"})
    })

    app.GET("/users/:id", func(c *kern.Context) {
        c.JSON(200, map[string]string{"id": c.Param("id")})
    })
    // Both :param and {param} syntax are supported interchangeably.

    _ = app.Run(":8080")
}

Core API

App
app := kern.New()
app := kern.Default()

app.Use(mw1, mw2)
app.GET("/", handler)
app.POST("/users", handler)
app.Group("/api")
app.Static("/static/", "./public")

// Test without a real HTTP server
client := kern.NewTestClient(app)
res := client.Get("/users")
res := client.PostJSON("/users", payload)

app.Run(":8080")
app.RunTLS(":8443", "cert.pem", "key.pem")

app.AddConstraints("GET", "/users/:id", kern.Constraints{
    Path: kern.PathConstraints{"id": kern.UintPathConstraint},
}, handler)

app.AddNamedConstraints("users_show", "GET", "/users/{id}", kern.Constraints{
    Path: kern.PathConstraints{"id": kern.UintPathConstraint},
}, handler)
Context

Request helpers:

  • Param(name)
  • Query(name) / DefaultQuery(name, fallback)
  • QueryPair(name1, name2) / QueryPairDefault(name1, fallback1, name2, fallback2)
  • QueryPairRaw(name1, name2) / QueryPairDefaultRaw(name1, fallback1, name2, fallback2)
  • QueryInt(name, fallback) / QueryBool(name, fallback)
  • Form(name)
  • Cookie(name)
  • GetHeader(name) / HeaderInt(name, fallback) / HeaderBool(name, fallback)
  • ClientIP()
  • Body()

Response helpers:

  • JSON(status, value)
  • OK(value) / Created(value) / Accepted(value)
  • Text(status, format, args...)
  • HTML(status, html)
  • XML(status, value)
  • Data(status, contentType, bytes)
  • NoContent(status)
  • Status(status)
  • JSONError(status, message, details...)
  • ETag(value) / LastModified(time) / IsNotModified(etag, modTime)
  • CheckPreconditions(etag, modTime)
  • Redirect(status, location)

Proxy safety options:

  • WithTrustedProxies(...) limits which upstream hops can supply forwarding headers.
  • WithStrictProxyHeaders(true) enforces strict parsing for X-Forwarded-For and X-Real-IP.
  • WithStrictRequestParsing(true) rejects malformed query strings in bind helpers.

Middleware

Built-in in core package:

  • kern.Logger()
  • kern.Recovery()
  • kern.CORS(...)

Extra middleware package:

  • github.com/mobentum/kern/middleware

Session middleware example:

import kmw "github.com/mobentum/kern/middleware"

app.Use(kmw.Session(kmw.SessionConfig{SigningKey: []byte("replace-with-strong-secret")}))

app.GET("/login", func(c *kern.Context) {
    session, _ := kmw.SessionFromContext(c.Context())
    session.Set("user_id", "123")
    _ = c.Text(http.StatusOK, "ok")
})

Route-level request guard example:

app.AddConstraints(http.MethodPost, "/upload", kern.Constraints{
    Validate: kmw.RequestGuard(kmw.RequestGuardConfig{
        MaxBodyBytes:      8 << 20,
        RequireBody:       true,
        RequireHeaders:    []string{"X-Tenant"},
        AllowContentTypes: []string{"application/json", "multipart/form-data"},
    }),
}, uploadHandler)

Optional Packages

Core Kern remains dependency-free. Optional integrations can live in separate modules.

Structured Logging (github.com/mobentum/kern/extensions/xlog)

xlog provides a slog-compatible logger backed by zerolog.

See full package docs and examples in extensions/xlog/README.md.

Runnable integration example: extensions/xlog/examples/kern-integration.

Install:

go get github.com/mobentum/kern/extensions/xlog

Use for app lifecycle logs:

import (
    "github.com/mobentum/kern"
    "github.com/mobentum/kern/extensions/xlog"
)

app := kern.New(
    kern.WithSlogLogger(xlog.NewLogger(xlog.Config{Format: "json"})),
)

Use for request middleware logs:

import (
    "github.com/mobentum/kern"
    "github.com/mobentum/kern/extensions/xlog"
)

reqLogger := xlog.NewLogger(xlog.Config{Format: "console"})

app := kern.New()
app.Use(kern.Logger(kern.LoggerConfig{
    SLogger: reqLogger,
    Fields: map[string]interface{}{
        "service": "users-api",
        "env":     "prod",
    },
}))
Configuration (github.com/mobentum/kern/extensions/xconfig)

xconfig provides dotenv-style loading and typed environment access through a small loader API.

See full package docs and examples in extensions/xconfig/README.md.

Runnable integration example: extensions/xconfig/examples/kern-integration.

Install:

go get github.com/mobentum/kern/extensions/xconfig

Use for app configuration:

import (
    "github.com/mobentum/kern/extensions/xconfig"
)

type Config struct {
    Host string
    Port int
}

func LoadConfig() (*Config, error) {
    loader, err := config.New(
        config.WithPrefix("APP"),
        config.WithDotEnv(".env"),
    )
    if err != nil {
        return nil, err
    }

    port, err := loader.Int("PORT", 8080)
    if err != nil {
        return nil, err
    }

    return &Config{
        Host: loader.String("HOST", "127.0.0.1"),
        Port: port,
    }, nil
}
OpenAPI (github.com/mobentum/kern/extensions/xopenapi)

xopenapi exposes a simple, explicit OpenAPI JSON endpoint and Swagger UI page.

See full package docs and examples in extensions/xopenapi/README.md.

Runnable integration example: extensions/xopenapi/examples/kern-integration.

Install:

go get github.com/mobentum/kern/extensions/xopenapi

Use for API docs endpoints:

import (
    "net/http"

    "github.com/mobentum/kern/extensions/xopenapi"
)

xopenapi.Register(app, xopenapi.Config{
    Info: xopenapi.Info{Title: "Users API", Version: "1.0.0"},
    Routes: []xopenapi.Route{
        {
            Method:      http.MethodGet,
            Path:        "/users/{id}",
            Summary:     "Get user",
            OperationID: "getUser",
            Tags:        []string{"users"},
        },
    },
})
OpenTelemetry Tracing (github.com/mobentum/kern/extensions/xotel)

xotel provides OpenTelemetry tracing middleware that creates a span per request.

See full package docs and examples in extensions/xotel/README.md.

Install:

go get github.com/mobentum/kern/extensions/xotel

Use for distributed tracing:

import (
    "github.com/mobentum/kern"
    "github.com/mobentum/kern/extensions/xotel"
)

app.Use(xotel.Middleware(xotel.Config{
    ServiceName: "users-api",
}))
Validation (github.com/mobentum/kern/extensions/xvalidator)

xvalidator wraps go-playground/validator for struct validation with custom rules, messages, and cross-field checks.

See full package docs and examples in extensions/xvalidator/README.md.

Runnable integration example: extensions/xvalidator/examples/kern-integration.

Install:

go get github.com/mobentum/kern/extensions/xvalidator

Use for request body validation:

import (
    "github.com/mobentum/kern"
    "github.com/mobentum/kern/extensions/xvalidator"
)

type createUserRequest struct {
    Name  string `json:"name"  validate:"required,min=3,max=50"`
    Email string `json:"email" validate:"required,email"`
}

app.POST("/users", func(c *kern.Context) {
    var req createUserRequest
    if err := c.DecodeJSON(&req); err != nil {
        c.Error(400, "invalid request body")
        return
    }
    if err := xvalidator.Validate(req); err != nil {
        c.JSON(422, map[string]interface{}{"error": "validation failed", "fields": err})
        return
    }
    c.Created(req)
})
gRPC (github.com/mobentum/kern/extensions/xgrpc)

xgrpc provides explicit gRPC server lifecycle management with optional health and reflection registration.

See full package docs and examples in extensions/xgrpc/README.md.

Runnable integration example: extensions/xgrpc/examples/kern-integration.

Install:

go get github.com/mobentum/kern/extensions/xgrpc

Use for gRPC server startup:

import (
    "context"
    "time"

    xgrpc "github.com/mobentum/kern/extensions/xgrpc"
)

srv, err := xgrpc.Register(xgrpc.Config{
    Addr:             ":9090",
    EnableHealth:     true,
    EnableReflection: true,
})
if err != nil {
    panic(err)
}

go func() {
    _ = srv.Run()
}()

shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
_ = srv.Shutdown(shutdownCtx)

Examples

Real runnable examples are in examples:

Run one:

cd examples/basic
go run .

Design Principles

  1. Small trusted core
  2. Standard-library first
  3. Explicit over implicit
  4. Performance with clarity
  5. Composable middleware over built-in monoliths

Status

Kern is production-usable today for APIs and internal services, with an active roadmap focused on middleware depth, validation, and observability.

Performance workflow

For the repeatable benchmark and pprof optimization process used in this repository, see benchmarks/fourway/README.md.

Roadmap tracking

Current implementation progress is tracked in ROADMAP_STATUS.md.

Hot handler query pattern

For handlers that repeatedly read a small fixed set of query fields, prefer the optional one-shot helpers to avoid repeated lookup and fallback branching in hot paths:

q, page := c.QueryPairDefaultRaw("q", "", "page", "1")
_ = c.TextPair(http.StatusOK, q, "-", page)

Use QueryPairDefault instead when URL-decoding behavior is required.

Contributing

Contributions are welcome. Please open an issue or pull request.

License

MIT License. See LICENSE.

Documentation

Overview

Package kern provides a lightweight web framework for Go.

kern is built on Go 1.22's enhanced net/http router with zero dependencies. It provides a simple, intuitive API for building web applications while leveraging the standard library's performance and reliability.

Example usage:

app := kern.Default()

app.GET("/", func(c *kern.Context) {
    c.JSON(200, map[string]string{"message": "Hello, kern!"})
})

app.Run(":8080")

Features:

  • Go 1.22+ native routing with method matching and path parameters
  • Standard http.Handler middleware pattern
  • Route groups for organization
  • Zero dependencies

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyRequestBody  = errors.New("request body is empty")
	ErrInvalidBindTarget = errors.New("bind target must be a non-nil pointer to struct")
)

Functions

func IntPathConstraint

func IntPathConstraint(value string) bool

IntPathConstraint validates signed base-10 integers.

func IsBodyTooLarge

func IsBodyTooLarge(err error) bool

IsBodyTooLarge reports whether err is caused by MaxBytesReader limits.

func LoggerFromContext added in v0.2.0

func LoggerFromContext(ctx context.Context) *slog.Logger

func RequestIDCtxKey added in v0.2.0

func RequestIDCtxKey() any

func RequestIDFromContext added in v1.0.1

func RequestIDFromContext(ctx context.Context) string

func SlugPathConstraint

func SlugPathConstraint(value string) bool

SlugPathConstraint validates URL-safe slugs ([a-zA-Z0-9_-]+).

func UUIDPathConstraint

func UUIDPathConstraint(value string) bool

UUIDPathConstraint validates canonical UUID format.

func UintPathConstraint

func UintPathConstraint(value string) bool

UintPathConstraint validates unsigned base-10 integers.

Types

type App

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

App is the main application instance

func Default

func Default() *App

Default instantiates an app with common settings

func New

func New(opts ...Option) *App

New instantiates a new app instance

func (*App) AddConstraints

func (app *App) AddConstraints(method, path string, constraints Constraints, handler HandlerFunc)

AddConstraints registers a handler with route-level constraints: typed path parameters and/or body validation middleware.

func (*App) AddNamedConstraints

func (app *App) AddNamedConstraints(name, method, path string, constraints Constraints, handler HandlerFunc)

AddNamedConstraints registers a named handler with route-level constraints.

func (*App) DELETE

func (app *App) DELETE(path string, handler HandlerFunc)

DELETE registers a DELETE route

func (*App) DELETENamed

func (app *App) DELETENamed(name, path string, handler HandlerFunc)

DELETENamed registers a named DELETE route.

func (*App) GET

func (app *App) GET(path string, handler HandlerFunc)

GET registers a GET route

func (*App) GETNamed

func (app *App) GETNamed(name, path string, handler HandlerFunc)

GETNamed registers a named GET route.

func (*App) Group

func (app *App) Group(prefix string, middlewares ...MiddlewareFunc) *Group

Group creates a route group with common prefix and middleware

func (*App) HEAD

func (app *App) HEAD(path string, handler HandlerFunc)

HEAD registers a HEAD route

func (*App) HEADNamed

func (app *App) HEADNamed(name, path string, handler HandlerFunc)

HEADNamed registers a named HEAD route.

func (*App) OPTIONS

func (app *App) OPTIONS(path string, handler HandlerFunc)

OPTIONS registers a OPTIONS route

func (*App) OPTIONSNamed

func (app *App) OPTIONSNamed(name, path string, handler HandlerFunc)

OPTIONSNamed registers a named OPTIONS route.

func (*App) OnError

func (app *App) OnError(hook ErrorHook)

OnError registers a callback for app-level server errors.

func (*App) OnListen

func (app *App) OnListen(hook ListenHook)

OnListen registers a callback for listen events.

func (*App) OnRoute

func (app *App) OnRoute(hook RouteHook)

OnRoute registers a callback for route registration events.

func (*App) OnShutdown

func (app *App) OnShutdown(hook ShutdownHook)

OnShutdown registers a callback for graceful shutdown events.

func (*App) PATCH

func (app *App) PATCH(path string, handler HandlerFunc)

PATCH registers a PATCH route

func (*App) PATCHNamed

func (app *App) PATCHNamed(name, path string, handler HandlerFunc)

PATCHNamed registers a named PATCH route.

func (*App) POST

func (app *App) POST(path string, handler HandlerFunc)

POST registers a POST route

func (*App) POSTNamed

func (app *App) POSTNamed(name, path string, handler HandlerFunc)

POSTNamed registers a named POST route.

func (*App) PUT

func (app *App) PUT(path string, handler HandlerFunc)

PUT registers a PUT route

func (*App) PUTNamed

func (app *App) PUTNamed(name, path string, handler HandlerFunc)

PUTNamed registers a named PUT route.

func (*App) Route

func (app *App) Route(method, path string, handler HandlerFunc)

Route registers a handler for the given method and path

func (*App) RouteByName

func (app *App) RouteByName(name string) (RouteInfo, bool)

RouteByName retrieves a route by its unique name.

func (*App) RouteNamed

func (app *App) RouteNamed(name, method, path string, handler HandlerFunc)

RouteNamed registers a named handler for the given method and path.

func (*App) Routes

func (app *App) Routes() []RouteInfo

Routes returns a snapshot of all registered routes.

func (*App) Run

func (app *App) Run(addr string, opts ...RunOption) error

Run starts the http server

func (*App) RunTLS

func (app *App) RunTLS(addr, certFile, keyFile string, opts ...RunOption) error

RunTLS starts the HTTPS server

func (*App) ServeHTTP

func (app *App) ServeHTTP(w http.ResponseWriter, r *http.Request)

ServeHTTP implements the handler for serving each request

func (*App) Static

func (app *App) Static(prefix, dir string)

func (*App) Use

func (app *App) Use(middlewares ...MiddlewareFunc)

Use adds a global middleware to the application

type BasicAuthConfig

type BasicAuthConfig struct {
	// Realm is used in the WWW-Authenticate response header.
	Realm string
	// Username is compared against incoming basic-auth username when ValidateCredentials is nil.
	Username string
	// Password is compared against incoming basic-auth password when ValidateCredentials is nil.
	Password string
	// ValidateCredentials provides custom username/password verification logic.
	ValidateCredentials func(username, password string, r *http.Request) bool
}

BasicAuthConfig configures HTTP basic authentication middleware.

type BearerAuthConfig

type BearerAuthConfig struct {
	// Realm is used in the WWW-Authenticate response header.
	Realm string
	// Token is compared against incoming bearer tokens when ValidateToken is nil.
	Token string
	// ValidateToken provides custom token verification logic.
	ValidateToken func(token string, r *http.Request) bool
}

BearerAuthConfig configures bearer token authentication middleware.

type CORSConfig

type CORSConfig struct {
	AllowOrigins      []string
	AllowMethods      []string
	AllowHeaders      []string
	ExposeHeaders     []string
	AllowCredentials  bool
	MaxAge            int
	PreflightContinue bool
}

type Constraints

type Constraints struct {
	Path     PathConstraints
	Validate MiddlewareFunc
}

Constraints bundles all route-level restrictions: path parameter constraints and optional body validation middleware. A zero value means no constraints.

type Context

type Context struct {
	Request  *http.Request
	Response http.ResponseWriter
	// contains filtered or unexported fields
}

Context adds helpful methods to the ongoing request

func (*Context) Accepted

func (c *Context) Accepted(data interface{}) error

Accepted sends a JSON 202 response.

func (*Context) Bind

func (c *Context) Bind(data interface{}) error

Bind automatically binds request data based on method and Content-Type, then validates the result using `validate` struct tags.

func (*Context) BindForm

func (c *Context) BindForm(data interface{}) error

BindForm binds request form values into a struct using `form` tags.

func (*Context) BindHeader

func (c *Context) BindHeader(data interface{}) error

BindHeader binds request headers into a struct using `header` tags.

func (*Context) BindQuery

func (c *Context) BindQuery(data interface{}) error

BindQuery binds URL query params into a struct using `query` tags.

func (*Context) Body

func (c *Context) Body() ([]byte, error)

Body reads the request body

func (*Context) CheckPreconditions

func (c *Context) CheckPreconditions(etag string, modTime time.Time) bool

CheckPreconditions evaluates HTTP conditional headers and writes 304/412 when applicable. It sets ETag and Last-Modified response headers when values are provided.

func (*Context) ClientIP

func (c *Context) ClientIP() string

ClientIP returns the client IP address. Use this if you trust request headers passed to the server (ie: reverse proxy sits before server) else use c.Request.RemoteAddr()

func (*Context) Context

func (c *Context) Context() context.Context

Context returns the request original context from context.Context

func (*Context) Cookie

func (c *Context) Cookie(name string) (*http.Cookie, error)

Cookie gets a request cookie by name

func (*Context) Created

func (c *Context) Created(data interface{}) error

Created sends a JSON 201 response.

func (*Context) Data

func (c *Context) Data(status int, contentType string, data []byte) error

Data sends raw bytes

func (*Context) DecodeJSON

func (c *Context) DecodeJSON(data interface{}) error

DecodeJSON decodes a request body into a struct

func (*Context) DecodeXML

func (c *Context) DecodeXML(data interface{}) error

DecodeXML decodes a request body into a struct

func (*Context) DefaultQuery

func (c *Context) DefaultQuery(name, defaultValue string) string

DefaultQuery gets query param with default value

func (*Context) DownloadFile

func (c *Context) DownloadFile(filepath string, downloadName string) error

DownloadFile sends a downloadable file response with the specified filename

func (*Context) ETag

func (c *Context) ETag(tag string) string

ETag sets the ETag response header and returns the normalized value.

func (*Context) Error

func (c *Context) Error(status int, message string) error

Error sends a JSON error response with a stable shape.

func (*Context) File

func (c *Context) File(name string) (*multipart.FileHeader, error)

File gets an uploaded file by key name. The file header containing the file is returned

func (*Context) Form

func (c *Context) Form(name string) string

Form gets a form value

func (*Context) GetHeader

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

GetHeader retrieves a request header by key

func (*Context) HTML

func (c *Context) HTML(status int, html string) error

func (*Context) HeaderBool

func (c *Context) HeaderBool(key string, defaultValue bool) (bool, error)

HeaderBool reads a boolean request header, returning defaultValue when absent.

func (*Context) HeaderInt

func (c *Context) HeaderInt(key string, defaultValue int) (int, error)

HeaderInt reads an integer request header, returning defaultValue when absent.

func (*Context) IsNotModified

func (c *Context) IsNotModified(etag string, modTime time.Time) bool

IsNotModified checks request cache validators and writes 304 when fresh. It also sets ETag and Last-Modified response headers when provided.

func (*Context) JSON

func (c *Context) JSON(status int, data interface{}) error

JSON sends a JSON response

func (*Context) JSONError

func (c *Context) JSONError(status int, message string, details ...interface{}) error

JSONError sends a structured JSON error payload. Pass an optional details value to attach machine-readable context.

func (*Context) LastModified

func (c *Context) LastModified(modTime time.Time)

LastModified sets the Last-Modified response header.

func (*Context) Logger

func (c *Context) Logger() *slog.Logger

Logger returns the request logger configured for this context.

It returns nil when no slog logger is configured on the app.

func (*Context) Method

func (c *Context) Method() string

Method returns the request method

func (*Context) NoContent

func (c *Context) NoContent(status int)

NoContent sends a response with no body

func (*Context) OK

func (c *Context) OK(data interface{}) error

OK sends a JSON 200 response.

func (*Context) Param

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

Param gets a path parameter by name. For example, this returns the value of id from /users/{id}

func (*Context) Path

func (c *Context) Path() string

Path retrieves the request path

func (*Context) Query

func (c *Context) Query(name string) string

Query returns a named query parameter

func (*Context) QueryBool

func (c *Context) QueryBool(name string, defaultValue bool) (bool, error)

QueryBool reads a boolean query parameter, returning defaultValue when absent.

func (*Context) QueryInt

func (c *Context) QueryInt(name string, defaultValue int) (int, error)

QueryInt reads an integer query parameter, returning defaultValue when absent.

func (*Context) QueryPair

func (c *Context) QueryPair(name1, name2 string) (string, string)

QueryPair returns two named query parameters using a single lookup path. This is useful in hot handlers that consistently read the same pair.

func (*Context) QueryPairDefault

func (c *Context) QueryPairDefault(name1, default1, name2, default2 string) (string, string)

QueryPairDefault returns two query parameters with independent defaults.

func (*Context) QueryPairDefaultRaw

func (c *Context) QueryPairDefaultRaw(name1, default1, name2, default2 string) (string, string)

QueryPairDefaultRaw returns two raw query parameters with independent defaults.

func (*Context) QueryPairRaw

func (c *Context) QueryPairRaw(name1, name2 string) (string, string)

QueryPairRaw returns two query parameters without URL decoding. This is a faster path for hot handlers when keys/values are plain ASCII.

func (*Context) Redirect

func (c *Context) Redirect(status int, url string)

Redirect redirects to a URL

func (*Context) SaveFile

func (c *Context) SaveFile(file *multipart.FileHeader, path string) error

SaveFile saves an uploaded file to the specified destination path.

func (*Context) ServeStatic

func (c *Context) ServeStatic(dir string) error

func (*Context) SetCookie

func (c *Context) SetCookie(cookie *http.Cookie)

SetCookie sets a response cookie

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader sets a response header

func (*Context) SetLogger

func (c *Context) SetLogger(logger *slog.Logger)

SetLogger overrides the logger for the current request context.

func (*Context) Status

func (c *Context) Status(status int)

Status sends a response status code with no body.

func (*Context) StreamFile

func (c *Context) StreamFile(filepath string) error

StreamFile streams the content of a file in chunks to the client

func (*Context) Text

func (c *Context) Text(status int, format string, values ...interface{}) error

Text sends a plain text response

func (*Context) TextPair

func (c *Context) TextPair(status int, left, sep, right string) error

TextPair sends a plain text response by joining left + sep + right without variadic formatting.

func (*Context) XML

func (c *Context) XML(status int, data interface{}) error

XML sends an XML response

type Error

type Error struct {
	Code    int
	Message string
}

Error represents a framework-level HTTP error.

func NewError

func NewError(code int, message string) *Error

NewError creates a new framework error with status code and message.

func (*Error) Error

func (e *Error) Error() string

type ErrorHook

type ErrorHook func(error)

ErrorHook is triggered when app-level server errors are observed.

type FieldValidationError

type FieldValidationError struct {
	Field string
	Tag   string
	Param string
	Value interface{}
}

FieldValidationError describes a single field validation failure.

type Group

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

Group is a route group with common named prefix

func (*Group) AddConstraints

func (g *Group) AddConstraints(method, path string, constraints Constraints, handler HandlerFunc)

AddConstraints registers a route with route-level constraints.

func (*Group) AddNamedConstraints

func (g *Group) AddNamedConstraints(name, method, path string, constraints Constraints, handler HandlerFunc)

AddNamedConstraints registers a named route with route-level constraints.

func (*Group) DELETE

func (g *Group) DELETE(path string, handler HandlerFunc)

DELETE registers a DELETE route for the group

func (*Group) DELETENamed

func (g *Group) DELETENamed(name, path string, handler HandlerFunc)

DELETENamed registers a named DELETE route for the group.

func (*Group) GET

func (g *Group) GET(path string, handler HandlerFunc)

GET registers a GET route for the group

func (*Group) GETNamed

func (g *Group) GETNamed(name, path string, handler HandlerFunc)

GETNamed registers a named GET route for the group.

func (*Group) Group

func (g *Group) Group(prefix string, middlewares ...MiddlewareFunc) *Group

Group creates a sub-group. Global middlewares come first in the chain

func (*Group) HEAD

func (g *Group) HEAD(path string, handler HandlerFunc)

HEAD registers a HEAD route for the group

func (*Group) HEADNamed

func (g *Group) HEADNamed(name, path string, handler HandlerFunc)

HEADNamed registers a named HEAD route for the group.

func (*Group) OPTIONS

func (g *Group) OPTIONS(path string, handler HandlerFunc)

OPTIONS registers a OPTIONS route for the group

func (*Group) OPTIONSNamed

func (g *Group) OPTIONSNamed(name, path string, handler HandlerFunc)

OPTIONSNamed registers a named OPTIONS route for the group.

func (*Group) PATCH

func (g *Group) PATCH(path string, handler HandlerFunc)

PATCH registers a PATCH route for the group

func (*Group) PATCHNamed

func (g *Group) PATCHNamed(name, path string, handler HandlerFunc)

PATCHNamed registers a named PATCH route for the group.

func (*Group) POST

func (g *Group) POST(path string, handler HandlerFunc)

POST registers a POST route for the group

func (*Group) POSTNamed

func (g *Group) POSTNamed(name, path string, handler HandlerFunc)

POSTNamed registers a named POST route for the group.

func (*Group) PUT

func (g *Group) PUT(path string, handler HandlerFunc)

PUT registers a PUT route for the group

func (*Group) PUTNamed

func (g *Group) PUTNamed(name, path string, handler HandlerFunc)

PUTNamed registers a named PUT route for the group.

func (*Group) Use

func (g *Group) Use(middlewares ...MiddlewareFunc)

Use registers middlewares to the group

type HandlerFunc

type HandlerFunc func(c *Context)

HandlerFunc is the handler signature

type JSONErrorPayload

type JSONErrorPayload struct {
	Error   string      `json:"error"`
	Details interface{} `json:"details,omitempty"`
}

JSONErrorPayload is the default structured payload for JSONError responses.

type ListenHook

type ListenHook func(ListenInfo)

ListenHook is triggered before a server starts listening.

type ListenInfo

type ListenInfo struct {
	Addr string
	TLS  bool
}

ListenInfo contains listen metadata for lifecycle hooks.

type LoggerConfig

type LoggerConfig struct {
	Format  string
	Logger  *log.Logger
	SLogger *slog.Logger
	Output  io.Writer
	Fields  map[string]interface{}
}

LoggerConfig configures request logging middleware output.

type MiddlewareFunc

type MiddlewareFunc func(http.Handler) http.Handler

MiddlewareFunc is the middleware signature

func BasicAuth

func BasicAuth(username, password string) MiddlewareFunc

BasicAuth validates Authorization: Basic <base64(username:password)>.

func BasicAuthWithConfig

func BasicAuthWithConfig(config BasicAuthConfig) MiddlewareFunc

BasicAuthWithConfig validates basic-auth credentials using either static credentials or ValidateCredentials.

func BearerAuth

func BearerAuth(token string) MiddlewareFunc

BearerAuth validates Authorization: Bearer <token> using a static token.

func BearerAuthWithConfig

func BearerAuthWithConfig(config BearerAuthConfig) MiddlewareFunc

BearerAuthWithConfig validates bearer tokens using either Token or ValidateToken.

func CORS

func CORS(allowOrigins []string) MiddlewareFunc

func CORSWithConfig

func CORSWithConfig(config CORSConfig) MiddlewareFunc

func Logger

func Logger(configs ...LoggerConfig) MiddlewareFunc

func Recovery

func Recovery() MiddlewareFunc

type Option

type Option func(*App)

Option configures the app

func WithBodyLimit

func WithBodyLimit(limit int64) Option

WithBodyLimit sets a max number of bytes readable from request bodies.

func WithDebug

func WithDebug() Option

WithDebug enables debug mode

func WithLogger

func WithLogger() Option

WithLogger adds logger middleware

func WithRecovery

func WithRecovery() Option

WithRecovery adds recovery middleware

func WithSlogLogger

func WithSlogLogger(logger *slog.Logger) Option

WithSlogLogger configures app lifecycle logging with slog.

func WithStrictProxyHeaders

func WithStrictProxyHeaders(enabled bool) Option

WithStrictProxyHeaders enables strict validation of forwarding headers. When enabled, malformed X-Forwarded-For or X-Real-IP values are ignored.

func WithStrictRequestParsing

func WithStrictRequestParsing(enabled bool) Option

WithStrictRequestParsing enables strict query parsing for binding helpers. When enabled, malformed URL query strings return errors in BindQuery/Bind.

func WithTrustedProxies

func WithTrustedProxies(entries ...string) Option

WithTrustedProxies configures reverse proxies whose forwarding headers are trusted. Entries may be plain IP addresses (e.g. "10.0.0.1") or CIDR blocks (e.g. "10.0.0.0/24").

type PathConstraint

type PathConstraint func(value string) bool

PathConstraint validates a single path parameter value.

type PathConstraints

type PathConstraints map[string]PathConstraint

PathConstraints maps path parameter names to validators.

type RouteHook

type RouteHook func(RouteInfo)

RouteHook is triggered when a route is registered.

type RouteInfo

type RouteInfo struct {
	Method string
	Path   string
	Name   string
}

RouteInfo contains route metadata for lifecycle hooks.

type RunOption

type RunOption func(*serverConfig)

RunOption configures the server

func WithGracefulShutdown

func WithGracefulShutdown(timeout time.Duration) RunOption

WithGracefulShutdown sets the graceful shutdown timeout.

func WithIdleTimeout

func WithIdleTimeout(duration time.Duration) RunOption

WithIdleTimeout sets the server idle timeout.

func WithKeepAlivesEnabled

func WithKeepAlivesEnabled(enabled bool) RunOption

WithKeepAlivesEnabled enables or disables HTTP keep-alives.

func WithMaxHeaderBytes

func WithMaxHeaderBytes(max int) RunOption

WithMaxHeaderBytes sets the server MaxHeaderBytes value.

func WithReadHeaderTimeout

func WithReadHeaderTimeout(duration time.Duration) RunOption

WithReadHeaderTimeout sets the server read header timeout.

func WithReadTimeout

func WithReadTimeout(duration time.Duration) RunOption

WithReadTimeout sets the server read timeout

func WithWriteTimeout

func WithWriteTimeout(duration time.Duration) RunOption

WithWriteTimeout sets the server write timeout

type ShutdownHook

type ShutdownHook func(error)

ShutdownHook is triggered when graceful shutdown exits.

type TestClient added in v0.1.3

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

TestClient provides concise, reusable request helpers for app tests.

func NewTestClient added in v0.1.3

func NewTestClient(app *App) *TestClient

NewTestClient creates a test client for the given app.

func (*TestClient) Delete added in v0.1.3

func (tc *TestClient) Delete(path string) *httptest.ResponseRecorder

Delete sends a DELETE request.

func (*TestClient) Do added in v0.1.3

Do sends a prepared request and returns the recorded response.

func (*TestClient) Get added in v0.1.3

func (tc *TestClient) Get(path string) *httptest.ResponseRecorder

Get sends a GET request to the given path.

func (*TestClient) Post added in v0.1.3

func (tc *TestClient) Post(path string, body io.Reader) *httptest.ResponseRecorder

Post sends a POST request with an optional body.

func (*TestClient) PostJSON added in v0.1.3

func (tc *TestClient) PostJSON(path string, payload interface{}) *httptest.ResponseRecorder

PostJSON sends a POST request with a JSON-encoded body.

func (*TestClient) Put added in v0.1.3

func (tc *TestClient) Put(path string, body io.Reader) *httptest.ResponseRecorder

Put sends a PUT request with an optional body.

func (*TestClient) Request added in v0.1.3

func (tc *TestClient) Request(method, path string, body io.Reader) *httptest.ResponseRecorder

Request creates a request with the given method, path, and body, then sends it.

func (*TestClient) WithHeader added in v0.1.3

func (tc *TestClient) WithHeader(key, value string) *TestClient

WithHeader sets a default header on all subsequent requests.

type ValidationErrors

type ValidationErrors []FieldValidationError

ValidationErrors contains all field validation errors.

func (ValidationErrors) Error

func (e ValidationErrors) Error() string

Directories

Path Synopsis
examples
basic command
file-download command
file-upload command
middleware command
nested-routes command
observability command
rest-api command
extensions
xconfig module
xlog module
xotel module
xvalidator module

Jump to

Keyboard shortcuts

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