httpsrv

package module
v2.0.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: Apache-2.0 Imports: 21 Imported by: 0

README

httpsrv

httpsrv is a lightweight, net/http-native web framework for Go. It offers a Fiber v3-style routing surface (App/Router/Ctx/Handler) implemented from scratch over the standard library.

Language: English | 中文

Features

  • net/http-native — the typical handler is func(Ctx) error; a stdlib http.Handler (e.g. http.HandlerFunc) is also accepted, so handlers interoperate directly with the Go ecosystem
  • Radix-tree routing — per-method trees, {param} and {*catchAll} path values, case-sensitive, static segments beat params beat catch-alls (order-independent)
  • Middleware & GroupsUse with fiber v3-style middleware (func(Ctx) error + c.Next()), global or prefix-scoped; Group(prefix) for prefix sharing
  • Static filesmiddleware/static exposes New(root) / FS(http.FS(embed)) returning an httpsrv.Handler: app.Get("/static/{*path}", static.New(root)); directory or embedded filesystem
  • Template renderinghtml/template parsed once, Ctx.Render(name, bind, layouts...)
  • i18n (opt-in) — flat locale message store, AcceptLanguage middleware (BCP-47 via x/text)
  • Compression (opt-in)middleware/compress exposes New(config...) (gzip/brotli by Accept-Encoding, brotli preferred)
  • Graceful server — safe default timeouts, Shutdown(ctx)

Documentation

Full guide (English): doc/Quick Start · Routing · Groups · Middleware · Server · Static · Ctx & Handler · Render · i18n · Examples · Index

中文文档:doc/zh-CN/

Installation

go get -u github.com/hooto/httpsrv/v2

Quick Start

package main

import (
    "github.com/hooto/httpsrv/v2"
)

func main() {
    app := httpsrv.New()

    app.Get("/", func(c httpsrv.Ctx) error {
        return c.SendString("hello httpsrv")
    })

    app.Run(":8080")
}

Run and try it:

$ go run .
$ curl http://localhost:8080/
hello httpsrv

See examples/ for runnable programs (hello, i18n, groups/static/render).

httpsrv keeps the core concise. Some recommended third-party libraries:

Database
Utility Libraries

More Go ecosystem libraries: awesome-go

System Requirements

  • Go Version: 1.26 or higher
  • Recommended Systems: Linux, Unix, or macOS

Reference Projects

httpsrv's API surface (App/Router/Ctx/Handler) is inspired by Fiber v3 — a from-scratch implementation over net/http with no dependency on fiber.

License

Apache License 2.0

Documentation

Index

Constants

View Source
const Version = "2.0.0-beta.1"

Version is the library version.

Variables

This section is empty.

Functions

This section is empty.

Types

type App

type App interface {
	Router

	// Run starts the HTTP server and blocks until it stops. Each optional arg
	// may be:
	//   - a string "host:port" or ":port" listen address (default ":8080"), or
	//   - a pre-bound net.Listener.
	// http.ErrServerClosed from a graceful stop is not reported as an error.
	Run(args ...any) error

	// Shutdown gracefully stops the server (see http.Server.Shutdown), waiting
	// for active connections to finish or ctx to expire. Call it from another
	// goroutine while Run is blocking.
	Shutdown(ctx context.Context) error
}

App is a self-contained HTTP application: a Router plus a Run entry point. Create one with New.

func New

func New(opts ...Option) App

New creates a new App. Pass options to configure it, e.g. WithViews or WithConfig(Config{Views: ...}).

type Config

type Config struct {
	// Addr is the listen address (default ":8080"; a string passed to Run
	// overrides it).
	Addr string

	// Timeouts; defaults are Read/Write 60s, ReadHeader 10s. Set WriteTimeout
	// to a large value (or use streaming) for long responses.
	ReadTimeout       time.Duration
	WriteTimeout      time.Duration
	ReadHeaderTimeout time.Duration

	// MaxHeaderBytes caps request header size (default 1 MiB).
	MaxHeaderBytes int

	// Views is the interface that wraps the Render function. Set it to a
	// template engine (e.g. a *Renderer from TemplatesDir/TemplatesFS) so
	// Handler code can call Ctx.Render. A custom engine implementing Views may
	// be plugged in here directly. Equivalent to WithViews.
	//
	// Default: nil
	Views Views `json:"-"`
}

Config holds server settings, applied at construction via WithConfig. Zero fields keep the defaults set in New.

type Ctx

type Ctx interface {
	// Request / Response
	Request() *http.Request
	Response() http.ResponseWriter
	// SetResponse replaces the response writer for the remainder of the chain.
	// Intended for middleware that wraps the writer (e.g. compression); route
	// handlers normally do not need it.
	SetResponse(w http.ResponseWriter)

	// Identity
	Method() string
	Path() string
	IP() string
	// BaseURL returns (protocol + host + base path).
	BaseURL() string
	// Locale returns the request locale (set by the AcceptLanguage middleware),
	// falling back to the i18n default, then "".
	Locale() string

	// Input
	Params(key string) string
	Query(key string, def ...string) string
	Header(key string, def ...string) string // request header
	Body() []byte
	FormValue(key string, def ...string) string // body form field (urlencoded or multipart)
	Bind(out any) error                         // JSON body -> out (json.Unmarshal)

	// Output (Status/SetHeader chain before the body is written)
	Status(code int) Ctx
	SetHeader(key, value string) // response header
	JSON(v any) error
	Send(b []byte) error
	SendString(s string) error
	Redirect(status int, url string) error
	Render(name string, bind any, layouts ...string) error // html template render
	Translate(locale, key string, args ...any) string      // i18n lookup (requires WithI18n)

	// Next runs the next handler in the middleware chain (fiber v3 style).
	// Middleware call it to continue; route handlers are terminal and ignore it.
	Next() error
}

Ctx carries the request/response state for a Handler. It is implemented over plain net/http and built per request; path params come from the standard library (r.PathValue, set by the router), so Ctx.Params needs no custom context wiring.

type ErrorHandler

type ErrorHandler func(c Ctx, err error)

ErrorHandler handles a non-nil error returned from a Handler. It may write a custom response (e.g. a JSON error body). If the Handler already wrote the response, further writes are superfluous. Set via WithErrorHandler; the default writes 500 + err.Error().

type Handler

type Handler func(ctx Ctx) error

Handler is the typical handler signature: it receives a Ctx and returns an error (nil on success). Route registrars (Get/Post/.../All) accept a Handler or, for direct stdlib interop, an http.Handler.

func AcceptLanguage

func AcceptLanguage(def string, others ...string) Handler

AcceptLanguage returns middleware that detects the request locale from the Accept-Language header and stores it in the request context (readable via Ctx.Locale). def is the default/fallback; others are additional supported locales. Matching uses golang.org/x/text/language (BCP-47), so an "en-US" request matches a supported "en", and "zh-Hans" matches "zh".

Register it with Use, e.g. app.Use(httpsrv.AcceptLanguage("en", "zh", "ja")).

type I18n

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

I18n is a locale message store: locale -> key -> text. Construct with NewI18n, add messages with Add/Set/LoadJSON, and read with Translate. For use in templates, pass i.Funcs() to TemplatesFS/TemplatesDir; for use in handlers, attach to the App with WithI18n (then Ctx.Translate / Ctx.Locale).

Locale keys are matched case-insensitively. Messages are flat key -> text (no plural forms). No date/number/currency/timezone formatting is included.

func NewI18n

func NewI18n(defaultLocale string) *I18n

NewI18n creates an i18n store; defaultLocale is the fallback for lookups whose locale is empty or has no entry (defaults to "en").

func (*I18n) Add

func (i *I18n) Add(locale string, msgs map[string]string)

Add merges flat {key: text} entries into locale.

func (*I18n) Default

func (i *I18n) Default() string

Default returns the configured default locale.

func (*I18n) Funcs

func (i *I18n) Funcs() template.FuncMap

Funcs returns the template function (T) bound to this store, for passing to TemplatesFS/TemplatesDir as extraFuncs when i18n is wanted in templates.

func (*I18n) LoadJSON

func (i *I18n) LoadJSON(locale string, data []byte) error

LoadJSON loads flat {"key": "text"} messages from JSON into locale.

func (*I18n) Set

func (i *I18n) Set(locale, key, text string)

Set sets a single key's text for locale.

func (*I18n) Translate

func (i *I18n) Translate(locale, key string, args ...any) string

Translate returns the text for key in locale (locale -> default -> key fallback), formatted via fmt.Sprintf when args are given.

type Option

type Option func(*app)

Option configures an App at construction.

func WithConfig

func WithConfig(cfg Config) Option

WithConfig applies server settings from cfg. Only non-zero fields override the defaults. Example:

app := httpsrv.New(httpsrv.WithConfig(httpsrv.Config{
    Addr:        ":3000",
    ReadTimeout: 30 * time.Second,
}))

func WithErrorHandler

func WithErrorHandler(h ErrorHandler) Option

WithErrorHandler sets a custom Handler-error handler.

func WithI18n

func WithI18n(i *I18n) Option

WithI18n attaches an opt-in i18n store so Handler code can call Ctx.Translate and Ctx.Locale. i18n is not loaded by default. For template use, also pass the store's Funcs() to TemplatesFS/TemplatesDir.

func WithViews

func WithViews(v Views) Option

WithViews attaches a template engine (a Views implementation, e.g. a *Renderer from TemplatesDir/TemplatesFS) so Handler code can call Ctx.Render. It is shorthand for WithConfig(Config{Views: v}); a custom Views engine may equally be plugged in via Config.Views.

type Renderer

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

Renderer is the template engine. It parses html/template files from a filesystem (a directory via TemplatesDir, or an embed/other fs.FS via TemplatesFS) once at construction, then renders them by name with optional layouts. Built-in template functions (raw, replace, upper, lower, date, datetime) are always available; pass extraFuncs to add more (e.g. an I18n store's Funcs() to get T). *Renderer implements Views.

func TemplatesDir

func TemplatesDir(root string, extraFuncs template.FuncMap) (*Renderer, error)

TemplatesDir builds a Renderer from the filesystem directory at root.

func TemplatesFS

func TemplatesFS(fsys fs.FS, extraFuncs template.FuncMap) (*Renderer, error)

TemplatesFS builds a Renderer from fsys (e.g. an embed.FS after fs.Sub). All .html/.tpl files are parsed immediately, so {{template "x"}} includes work.

func (*Renderer) Load

func (r *Renderer) Load() error

Load is a no-op: templates are parsed once at construction (TemplatesFS/ TemplatesDir), so by the time a Renderer is attached there is nothing left to load. It satisfies the Views interface.

func (*Renderer) Render

func (r *Renderer) Render(w io.Writer, name string, bind any, layout ...string) error

Render renders name with bind into w, wrapping the output in each layout in order (the last layout is the outermost). It implements Views.

type Router

type Router interface {
	// Get/Post/.../All accept a Handler (func(Ctx) error, the typical form) or an
	// http.Handler (for direct stdlib interop); a Handler receives a request
	// context (Ctx).
	Get(path string, handler any) Router
	Head(path string, handler any) Router
	Post(path string, handler any) Router
	Put(path string, handler any) Router
	Patch(path string, handler any) Router
	Delete(path string, handler any) Router
	Options(path string, handler any) Router
	All(path string, handler any) Router

	// Use registers middleware. With a leading string argument it scopes the
	// middleware to that path prefix (segment-aware, all methods); without one
	// it runs for every request.
	Use(args ...any) Router

	// Group returns a sub-router whose routes are prefixed with prefix.
	// Groups nest: a group created from another group inherits its prefix.
	Group(prefix string) Router
}

Router is the shared route-registration surface implemented by both the App and route Groups. Each method registers a handler for one HTTP method and returns the receiver, so calls chain.

type Views

type Views interface {
	// Load is called once to load/parse templates. The built-in Renderer
	// parses at construction, so its Load is a no-op.
	Load() error

	// Render writes the named template (with optional layouts) to w.
	Render(w io.Writer, name string, bind any, layout ...string) error
}

Views is the interface that wraps the Render function. A template engine implements it so Handler code can call Ctx.Render. The built-in *Renderer satisfies it; plug in a custom engine via WithViews or WithConfig(Config{Views: ...}).

Default: nil

Directories

Path Synopsis
examples
group command
Example: groups, path params, static files, and template rendering.
Example: groups, path params, static files, and template rendering.
hello command
Example: the smallest possible v2 app.
Example: the smallest possible v2 app.
i18n command
Example: loading i18n messages from local JSON files.
Example: loading i18n messages from local JSON files.
internal
lru
Package lru implements an LRU cache.
Package lru implements an LRU cache.
radix
Package radix implements a generic radix tree for HTTP route matching.
Package radix implements a generic radix tree for HTTP route matching.
middleware
compress
Package compress provides response-compression middleware for httpsrv, mirroring gofiber v3's middleware/compress API (New(config) -> Handler).
Package compress provides response-compression middleware for httpsrv, mirroring gofiber v3's middleware/compress API (New(config) -> Handler).
static
Package static provides a static-file handler for httpsrv.
Package static provides a static-file handler for httpsrv.

Jump to

Keyboard shortcuts

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