zinc

package module
v0.1.2 Latest Latest
Warning

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

Go to latest
Published: Apr 13, 2026 License: MIT Imports: 33 Imported by: 0

README

Version Go Version Docs Coverage License

Zinc

Zinc is an Express-inspired, idiomatic Go API framework built on net/http.

Features
  • Express-style routes with :param and *wildcard
  • Route groups, prefix middleware, and route metadata
  • Binding helpers for path, query, headers, JSON, XML, and forms
  • Response helpers for JSON, XML, HTML, streams, redirects, files, and rendering
  • First-party template renderer helper for html/template and text/template
  • Static/file serving and stdlib handler interop through Mount, Wrap, and WrapFunc
  • Explicit startup and shutdown with Listen, Serve, and Shutdown

Installation

go get github.com/0mjs/zinc

Quick Start

package main

import (
	"log"

	"github.com/0mjs/zinc"
	middleware "github.com/0mjs/zinc/middleware"
)

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

	app.Use(middleware.RequestLogger())

	app.Get("/", "Hello, world!") // Shorthand

	app.Get("/greet", func(c *zinc.Context) error {
		return c.JSON(zinc.Map{
			"greeting": "Hello, world!",
		})
	})

	api := app.Group("/api")
	api.Get("/health", func(c *zinc.Context) error {
		return c.String("ok")
	})

	log.Fatal(app.Listen(":8080"))
}

Routing And Middleware

app.Use(middleware.RequestLogger())
app.UsePrefix("/api", authMiddleware)

app.Route("/api", func(api *zinc.Group) {
	api.Get("/users/:id", showUser)
	api.Post("/users", createUser)
})

Binding And Responses

type CreateUserInput struct {
	TeamID int    `path:"teamID"`
	Page   int    `query:"page"`
	Name   string `json:"name"`
	Auth   string `header:"x-auth"`
}

app.Post("/teams/:teamID/users", func(c *zinc.Context) error {
	var input CreateUserInput
	if err := c.Bind().All(&input); err != nil {
		return err
	}

	return c.Status(zinc.StatusCreated).JSON(input)
})

Configuration

app := zinc.NewWithConfig(zinc.Config{
	ServerHeader:           "zinc/example",
	CaseSensitive:          true,
	StrictRouting:          true,
	AutoHead:               true,
	AutoOptions:            true,
	HandleMethodNotAllowed: true,
	BodyLimit:              8 << 20,
	ProxyHeader:            zinc.HeaderXForwardedFor,
	TrustedProxies:         []string{"10.0.0.1"},
})

Config also lets you plug in a custom RequestBinder, Validator, Renderer, JSONCodec, and ErrorHandler.

views := template.Must(template.ParseGlob("templates/*.html"))

app := zinc.NewWithConfig(zinc.Config{
	Renderer: zinc.NewHTMLTemplateRenderer(
		views,
		zinc.WithTemplateSuffixes(".html", ".tmpl"),
	),
})

app.Get("/dashboard", func(c *zinc.Context) error {
	return c.Render("dashboard", zinc.Map{"Title": "Overview"})
})

Quality Snapshot

Latest local coverage run (go test -count=1 ./... -coverprofile=coverage.out):

Overall                                      [#################...] 83.4%
Core (github.com/0mjs/zinc)                  [#################...] 83.3%
Middleware (github.com/0mjs/zinc/middleware) [#################...] 83.9%

Benchmark Snapshot

Latest local peer-only snapshot (Apple M1 Pro, darwin/arm64, count=1 rerun on 2026-03-18):

  • Zinc wins 65/85 rows overall against Gin, Echo, and Chi.
  • Excluding throughput, Zinc wins 65/77 rows.
  • Full tables and remaining gaps live in BENCKMARKS.md.

Selected highlights:

Benchmark Zinc Gin Echo Chi Winner
HelloWorld 61.82 ns 88.21 ns 127.2 ns 178.8 ns 🥇 Zinc
APIHappyPath 1.25 µs 3.02 µs 2.19 µs 1.66 µs 🥇 Zinc
APIBindJSONHappyPath 2.41 µs 4.41 µs 2.52 µs 2.81 µs 🥇 Zinc
StaticFileHit 15.64 µs 32.85 µs 26.95 µs 15.97 µs 🥇 Zinc
RouteRegistrationStatic 57.88 µs 76.33 µs 337.4 µs 85.04 µs 🥇 Zinc
ScenarioAll/ParseAPI26 118.2 ns 120.9 ns 155.4 ns 370.9 ns 🥇 Zinc

Throughput is currently the weakest category in the peer-only suite; the detailed breakdown is in BENCKMARKS.md.

Optional Middleware

Zinc ships middleware behind one unified import:

  • github.com/0mjs/zinc/middleware
import (
	"log"
	"os"
	"time"

	"github.com/0mjs/zinc"
	"github.com/0mjs/zinc/middleware"
	jwt "github.com/golang-jwt/jwt/v5"
)

app.Use(middleware.BodyDump(func(c *zinc.Context, snapshot middleware.BodyDumpSnapshot) {
	log.Printf("%s %s -> %d", snapshot.Method, snapshot.Path, snapshot.Status)
}))

app.Use(middleware.Recover())
app.Use(middleware.RequestID())
app.Use(middleware.CORS("https://app.example.com"))
app.Use(middleware.Decompress())
app.Use(middleware.Gzip())
app.Use(middleware.MethodOverride())
app.Use(middleware.Secure())
app.Use(middleware.TrailingSlash())
app.Use(middleware.KeyAuth(middleware.KeyAuthStatic(os.Getenv("API_KEY"))))
app.Use(middleware.Prometheus())

app.Get("/metrics", middleware.PrometheusHandler())

admin := app.Group("/admin")
admin.Use(middleware.BodyLimit(256 * middleware.KB))
admin.Use(middleware.ContextTimeout(250 * time.Millisecond))

app.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
	ExposeHeader: zinc.HeaderXCSRFToken,
}))

app.Use(middleware.BasicAuthWithConfig(middleware.BasicAuthConfig{
	Validator: middleware.BasicAuthStatic("admin", os.Getenv("ADMIN_PASSWORD")),
}))

app.Use(middleware.JWTWithConfig(middleware.JWTConfig{
	KeyFunc: func(*zinc.Context, *jwt.Token) (any, error) {
		return []byte("secret"), nil
	},
}))

Zinc now exposes middleware through a single public package: github.com/0mjs/zinc/middleware.

License

MIT

Documentation

Index

Constants

View Source
const (
	ParamIdentifier    = ':'
	WildcardIdentifier = '*'
)
View Source
const (
	HeaderAuthorization                   = "Authorization"
	HeaderProxyAuthenticate               = "Proxy-Authenticate"
	HeaderProxyAuthorization              = "Proxy-Authorization"
	HeaderWWWAuthenticate                 = "WWW-Authenticate"
	HeaderAge                             = "Age"
	HeaderCacheControl                    = "Cache-Control"
	HeaderClearSiteData                   = "Clear-Site-Data"
	HeaderExpires                         = "Expires"
	HeaderPragma                          = "Pragma"
	HeaderWarning                         = "Warning"
	HeaderAcceptCH                        = "Accept-CH"
	HeaderAcceptCHLifetime                = "Accept-CH-Lifetime"
	HeaderContentDPR                      = "Content-DPR"
	HeaderDPR                             = "DPR"
	HeaderEarlyData                       = "Early-Data"
	HeaderSaveData                        = "Save-Data"
	HeaderViewportWidth                   = "Viewport-Width"
	HeaderWidth                           = "Width"
	HeaderETag                            = "ETag"
	HeaderIfMatch                         = "If-Match"
	HeaderIfModifiedSince                 = "If-Modified-Since"
	HeaderIfNoneMatch                     = "If-None-Match"
	HeaderIfUnmodifiedSince               = "If-Unmodified-Since"
	HeaderLastModified                    = "Last-Modified"
	HeaderVary                            = "Vary"
	HeaderConnection                      = "Connection"
	HeaderKeepAlive                       = "Keep-Alive"
	HeaderAccept                          = "Accept"
	HeaderAcceptCharset                   = "Accept-Charset"
	HeaderAcceptEncoding                  = "Accept-Encoding"
	HeaderAcceptLanguage                  = "Accept-Language"
	HeaderCookie                          = "Cookie"
	HeaderExpect                          = "Expect"
	HeaderMaxForwards                     = "Max-Forwards"
	HeaderSetCookie                       = "Set-Cookie"
	HeaderSecFetchSite                    = "Sec-Fetch-Site"
	HeaderAccessControlAllowCredentials   = "Access-Control-Allow-Credentials"
	HeaderAccessControlAllowHeaders       = "Access-Control-Allow-Headers"
	HeaderAccessControlAllowMethods       = "Access-Control-Allow-Methods"
	HeaderAccessControlAllowOrigin        = "Access-Control-Allow-Origin"
	HeaderAccessControlExposeHeaders      = "Access-Control-Expose-Headers"
	HeaderAccessControlMaxAge             = "Access-Control-Max-Age"
	HeaderAccessControlRequestHeaders     = "Access-Control-Request-Headers"
	HeaderAccessControlRequestMethod      = "Access-Control-Request-Method"
	HeaderOrigin                          = "Origin"
	HeaderTimingAllowOrigin               = "Timing-Allow-Origin"
	HeaderXPermittedCrossDomainPolicies   = "X-Permitted-Cross-Domain-Policies"
	HeaderDNT                             = "DNT"
	HeaderTk                              = "Tk"
	HeaderContentDisposition              = "Content-Disposition"
	HeaderContentEncoding                 = "Content-Encoding"
	HeaderContentLanguage                 = "Content-Language"
	HeaderContentLength                   = "Content-Length"
	HeaderContentLocation                 = "Content-Location"
	HeaderContentType                     = "Content-Type"
	HeaderForwarded                       = "Forwarded"
	HeaderVia                             = "Via"
	HeaderXForwardedFor                   = "X-Forwarded-For"
	HeaderXForwardedHost                  = "X-Forwarded-Host"
	HeaderXForwardedProto                 = "X-Forwarded-Proto"
	HeaderXForwardedProtocol              = "X-Forwarded-Protocol"
	HeaderXForwardedSsl                   = "X-Forwarded-Ssl"
	HeaderXUrlScheme                      = "X-Url-Scheme"
	HeaderLocation                        = "Location"
	HeaderFrom                            = "From"
	HeaderHost                            = "Host"
	HeaderReferer                         = "Referer"
	HeaderReferrerPolicy                  = "Referrer-Policy"
	HeaderUserAgent                       = "User-Agent"
	HeaderAllow                           = "Allow"
	HeaderServer                          = "Server"
	HeaderAcceptRanges                    = "Accept-Ranges"
	HeaderContentRange                    = "Content-Range"
	HeaderIfRange                         = "If-Range"
	HeaderRange                           = "Range"
	HeaderContentSecurityPolicy           = "Content-Security-Policy"
	HeaderContentSecurityPolicyReportOnly = "Content-Security-Policy-Report-Only"
	HeaderCrossOriginResourcePolicy       = "Cross-Origin-Resource-Policy"
	HeaderExpectCT                        = "Expect-CT"
	HeaderFeaturePolicy                   = "Feature-Policy"
	HeaderPublicKeyPins                   = "Public-Key-Pins"
	HeaderPublicKeyPinsReportOnly         = "Public-Key-Pins-Report-Only"
	HeaderStrictTransportSecurity         = "Strict-Transport-Security"
	HeaderUpgradeInsecureRequests         = "Upgrade-Insecure-Requests"
	HeaderXContentTypeOptions             = "X-Content-Type-Options"
	HeaderXDownloadOptions                = "X-Download-Options"
	HeaderXFrameOptions                   = "X-Frame-Options"
	HeaderXPoweredBy                      = "X-Powered-By"
	HeaderXCSRFToken                      = "X-CSRF-Token"
	HeaderXXSSProtection                  = "X-XSS-Protection"
	HeaderLastEventID                     = "Last-Event-ID"
	HeaderNEL                             = "NEL"
	HeaderPingFrom                        = "Ping-From"
	HeaderPingTo                          = "Ping-To"
	HeaderReportTo                        = "Report-To"
	HeaderTE                              = "TE"
	HeaderTrailer                         = "Trailer"
	HeaderTransferEncoding                = "Transfer-Encoding"
	HeaderSecWebSocketAccept              = "Sec-WebSocket-Accept"
	HeaderSecWebSocketExtensions          = "Sec-WebSocket-Extensions"
	HeaderSecWebSocketKey                 = "Sec-WebSocket-Key"
	HeaderSecWebSocketProtocol            = "Sec-WebSocket-Protocol"
	HeaderSecWebSocketVersion             = "Sec-WebSocket-Version"
	HeaderAcceptPatch                     = "Accept-Patch"
	HeaderAcceptPushPolicy                = "Accept-Push-Policy"
	HeaderAcceptSignature                 = "Accept-Signature"
	HeaderAltSvc                          = "Alt-Svc"
	HeaderDate                            = "Date"
	HeaderIndex                           = "Index"
	HeaderLargeAllocation                 = "Large-Allocation"
	HeaderLink                            = "Link"
	HeaderPushPolicy                      = "Push-Policy"
	HeaderRetryAfter                      = "Retry-After"
	HeaderServerTiming                    = "Server-Timing"
	HeaderSignature                       = "Signature"
	HeaderSignedHeaders                   = "Signed-Headers"
	HeaderSourceMap                       = "SourceMap"
	HeaderUpgrade                         = "Upgrade"
	HeaderXDNSPrefetchControl             = "X-DNS-Prefetch-Control"
	HeaderXPingback                       = "X-Pingback"
	HeaderXRequestID                      = "X-Request-ID"
	HeaderXRequestedWith                  = "X-Requested-With"
	HeaderXRobotsTag                      = "X-Robots-Tag"
	HeaderXUACompatible                   = "X-UA-Compatible"
)
View Source
const (
	MethodGet     = "GET"     // RFC 7231, 4.3.1
	MethodHead    = "HEAD"    // RFC 7231, 4.3.2
	MethodPost    = "POST"    // RFC 7231, 4.3.3
	MethodPut     = "PUT"     // RFC 7231, 4.3.4
	MethodPatch   = "PATCH"   // RFC 5789
	MethodDelete  = "DELETE"  // RFC 7231, 4.3.5
	MethodConnect = "CONNECT" // RFC 7231, 4.3.6
	MethodOptions = "OPTIONS" // RFC 7231, 4.3.7
	MethodTrace   = "TRACE"   // RFC 7231, 4.3.8

)

HTTP methods

View Source
const (
	StatusContinue                      = 100 // RFC 7231, 6.2.1
	StatusSwitchingProtocols            = 101 // RFC 7231, 6.2.2
	StatusProcessing                    = 102 // RFC 2518, 10.1
	StatusEarlyHints                    = 103 // RFC 8297
	StatusOK                            = 200 // RFC 7231, 6.3.1
	StatusCreated                       = 201 // RFC 7231, 6.3.2
	StatusAccepted                      = 202 // RFC 7231, 6.3.3
	StatusNonAuthoritativeInformation   = 203 // RFC 7231, 6.3.4
	StatusNoContent                     = 204 // RFC 7231, 6.3.5
	StatusResetContent                  = 205 // RFC 7231, 6.3.6
	StatusPartialContent                = 206 // RFC 7233, 4.1
	StatusMultiStatus                   = 207 // RFC 4918, 11.1
	StatusAlreadyReported               = 208 // RFC 5842, 7.1
	StatusIMUsed                        = 226 // RFC 3229, 10.4.1
	StatusMultipleChoices               = 300 // RFC 7231, 6.4.1
	StatusMovedPermanently              = 301 // RFC 7231, 6.4.2
	StatusFound                         = 302 // RFC 7231, 6.4.3
	StatusSeeOther                      = 303 // RFC 7231, 6.4.4
	StatusNotModified                   = 304 // RFC 7232, 4.1
	StatusUseProxy                      = 305 // RFC 7231, 6.4.5
	StatusTemporaryRedirect             = 307 // RFC 7231, 6.4.7
	StatusPermanentRedirect             = 308 // RFC 7538, 3
	StatusBadRequest                    = 400 // RFC 7231, 6.5.1
	StatusUnauthorized                  = 401 // RFC 7235, 3.1
	StatusPaymentRequired               = 402 // RFC 7231, 6.5.2
	StatusForbidden                     = 403 // RFC 7231, 6.5.3
	StatusNotFound                      = 404 // RFC 7231, 6.5.4
	StatusMethodNotAllowed              = 405 // RFC 7231, 6.5.5
	StatusNotAcceptable                 = 406 // RFC 7231, 6.5.6
	StatusProxyAuthRequired             = 407 // RFC 7235, 3.2
	StatusRequestTimeout                = 408 // RFC 7231, 6.5.7
	StatusConflict                      = 409 // RFC 7231, 6.5.8
	StatusGone                          = 410 // RFC 7231, 6.5.9
	StatusLengthRequired                = 411 // RFC 7231, 6.5.10
	StatusPreconditionFailed            = 412 // RFC 7232, 4.2
	StatusRequestEntityTooLarge         = 413 // RFC 7231, 6.5.11
	StatusRequestURITooLong             = 414 // RFC 7231, 6.5.12
	StatusUnsupportedMediaType          = 415 // RFC 7231, 6.5.13
	StatusRequestedRangeNotSatisfiable  = 416 // RFC 7233, 4.4
	StatusExpectationFailed             = 417 // RFC 7231, 6.5.14
	StatusTeapot                        = 418 // RFC 7168, 2.3.3
	StatusMisdirectedRequest            = 421 // RFC 7540, 9.1.2
	StatusUnprocessableEntity           = 422 // RFC 4918, 11.2
	StatusLocked                        = 423 // RFC 4918, 11.3
	StatusFailedDependency              = 424 // RFC 4918, 11.4
	StatusTooEarly                      = 425 // RFC 8470, 5.2.
	StatusUpgradeRequired               = 426 // RFC 7231, 6.5.15
	StatusPreconditionRequired          = 428 // RFC 6585, 3
	StatusTooManyRequests               = 429 // RFC 6585, 4
	StatusRequestHeaderFieldsTooLarge   = 431 // RFC 6585, 5
	StatusUnavailableForLegalReasons    = 451 // RFC 7725, 3
	StatusInternalServerError           = 500 // RFC 7231, 6.6.1
	StatusNotImplemented                = 501 // RFC 7231, 6.6.2
	StatusBadGateway                    = 502 // RFC 7231, 6.6.3
	StatusServiceUnavailable            = 503 // RFC 7231, 6.6.4
	StatusGatewayTimeout                = 504 // RFC 7231, 6.6.5
	StatusHTTPVersionNotSupported       = 505 // RFC 7231, 6.6.6
	StatusVariantAlsoNegotiates         = 506 // RFC 2295, 8.1
	StatusInsufficientStorage           = 507 // RFC 4918, 11.5
	StatusLoopDetected                  = 508 // RFC 5842, 7.2
	StatusNotExtended                   = 510 // RFC 2774, 7
	StatusNetworkAuthenticationRequired = 511 // RFC 6585, 6
)

HTTP status codes

View Source
const Version = "0.1.2"

Version is the current version of Zinc. This should be updated for each release.

Variables

View Source
var (
	ErrBadRequest                    = NewError(StatusBadRequest)
	ErrUnauthorized                  = NewError(StatusUnauthorized)
	ErrPaymentRequired               = NewError(StatusPaymentRequired)
	ErrForbidden                     = NewError(StatusForbidden)
	ErrNotFound                      = NewError(StatusNotFound)
	ErrMethodNotAllowed              = NewError(StatusMethodNotAllowed)
	ErrNotAcceptable                 = NewError(StatusNotAcceptable)
	ErrProxyAuthRequired             = NewError(StatusProxyAuthRequired)
	ErrRequestTimeout                = NewError(StatusRequestTimeout)
	ErrConflict                      = NewError(StatusConflict)
	ErrGone                          = NewError(StatusGone)
	ErrLengthRequired                = NewError(StatusLengthRequired)
	ErrPreconditionFailed            = NewError(StatusPreconditionFailed)
	ErrRequestEntityTooLarge         = NewError(StatusRequestEntityTooLarge)
	ErrRequestURITooLong             = NewError(StatusRequestURITooLong)
	ErrUnsupportedMediaType          = NewError(StatusUnsupportedMediaType)
	ErrRequestedRangeNotSatisfiable  = NewError(StatusRequestedRangeNotSatisfiable)
	ErrExpectationFailed             = NewError(StatusExpectationFailed)
	ErrTeapot                        = NewError(StatusTeapot)
	ErrMisdirectedRequest            = NewError(StatusMisdirectedRequest)
	ErrUnprocessableEntity           = NewError(StatusUnprocessableEntity)
	ErrLocked                        = NewError(StatusLocked)
	ErrFailedDependency              = NewError(StatusFailedDependency)
	ErrTooEarly                      = NewError(StatusTooEarly)
	ErrUpgradeRequired               = NewError(StatusUpgradeRequired)
	ErrPreconditionRequired          = NewError(StatusPreconditionRequired)
	ErrTooManyRequests               = NewError(StatusTooManyRequests)
	ErrRequestHeaderFieldsTooLarge   = NewError(StatusRequestHeaderFieldsTooLarge)
	ErrUnavailableForLegalReasons    = NewError(StatusUnavailableForLegalReasons)
	ErrInternalServerError           = NewError(StatusInternalServerError)
	ErrNotImplemented                = NewError(StatusNotImplemented)
	ErrBadGateway                    = NewError(StatusBadGateway)
	ErrServiceUnavailable            = NewError(StatusServiceUnavailable)
	ErrGatewayTimeout                = NewError(StatusGatewayTimeout)
	ErrHTTPVersionNotSupported       = NewError(StatusHTTPVersionNotSupported)
	ErrVariantAlsoNegotiates         = NewError(StatusVariantAlsoNegotiates)
	ErrInsufficientStorage           = NewError(StatusInsufficientStorage)
	ErrLoopDetected                  = NewError(StatusLoopDetected)
	ErrNotExtended                   = NewError(StatusNotExtended)
	ErrNetworkAuthenticationRequired = NewError(StatusNetworkAuthenticationRequired)
)
View Source
var (
	ErrTemplateEngineNotConfigured = errors.New("template engine is not configured")
	ErrTemplateNameRequired        = errors.New("template name is required")
	ErrTemplateNotFound            = errors.New("template not found")
)
View Source
var DefaultConfig = Config{
	ServerHeader:           "",
	CaseSensitive:          false,
	StrictRouting:          false,
	AutoHead:               true,
	AutoOptions:            true,
	HandleMethodNotAllowed: true,
	BodyLimit:              4 << 20,
	ReadTimeout:            5 * time.Second,
	WriteTimeout:           10 * time.Second,
	IdleTimeout:            120 * time.Second,
	ProxyHeader:            "X-Forwarded-For",
	TrustedProxies:         nil,
	RouteCacheSize:         1000,
}

DefaultConfig is the baseline Zinc configuration.

View Source
var ErrResponseAlreadySent = errors.New("response already sent")

Functions

func GetVersion

func GetVersion() string

GetVersion returns the current version of Zinc.

func GetVersionHeader

func GetVersionHeader() string

GetVersionHeader returns the full version string for HTTP headers.

Types

type App

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

func New

func New() *App

func NewWithConfig

func NewWithConfig(cfg Config) *App

func (*App) AcquireContext added in v0.1.0

func (a *App) AcquireContext(w http.ResponseWriter, r *http.Request) *Context

func (*App) Add

func (a *App) Add(method, path string, handlers ...HandlerFunc) error

func (*App) All

func (a *App) All(path string, handlers ...HandlerFunc) error

func (*App) Any

func (a *App) Any(path string, handlers ...HandlerFunc) error

func (*App) Connect

func (a *App) Connect(path string, handlers ...HandlerFunc) error

func (*App) Delete

func (a *App) Delete(path string, handlers ...HandlerFunc) error

func (*App) File

func (a *App) File(path, file string) error

func (*App) FileFS

func (a *App) FileFS(path, file string, filesystem fs.FS) error

func (*App) FindRoute added in v0.1.0

func (a *App) FindRoute(method, path string) (RouteInfo, bool)

func (*App) Get

func (a *App) Get(path string, handlers ...any) error

func (*App) Group

func (a *App) Group(prefix string, handlers ...HandlerFunc) *Group

func (*App) Handle added in v0.1.0

func (a *App) Handle(spec RouteSpec) error

func (*App) Handler

func (a *App) Handler() http.Handler

func (*App) Head

func (a *App) Head(path string, handlers ...HandlerFunc) error

func (*App) Listen

func (a *App) Listen(addr string) error

func (*App) ListenTLS

func (a *App) ListenTLS(addr, certFile, keyFile string) error

func (*App) Match

func (a *App) Match(methods []string, path string, handlers ...HandlerFunc) error

func (*App) MethodNotAllowed

func (a *App) MethodNotAllowed(handler HandlerFunc)

func (*App) Mount

func (a *App) Mount(prefix string, h http.Handler)

func (*App) NotFound

func (a *App) NotFound(handler HandlerFunc)

func (*App) Options

func (a *App) Options(path string, handlers ...HandlerFunc) error

func (*App) Patch

func (a *App) Patch(path string, handlers ...HandlerFunc) error

func (*App) Post

func (a *App) Post(path string, handlers ...HandlerFunc) error

func (*App) Put

func (a *App) Put(path string, handlers ...HandlerFunc) error

func (*App) ReleaseContext added in v0.1.0

func (a *App) ReleaseContext(c *Context)

func (*App) Route

func (a *App) Route(prefix string, fn func(*Group), handlers ...HandlerFunc) *Group

func (*App) RouteByName added in v0.1.0

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

func (*App) RouteNotFound added in v0.1.0

func (a *App) RouteNotFound(path string, handlers ...HandlerFunc) error

func (*App) Routes

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

func (*App) RoutesByMethod added in v0.1.0

func (a *App) RoutesByMethod(method string) []RouteInfo

func (*App) RoutesByPrefix added in v0.1.0

func (a *App) RoutesByPrefix(prefix string) []RouteInfo

func (*App) Serve

func (a *App) Serve(ln net.Listener) error

func (*App) ServeHTTP

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

func (*App) Shutdown

func (a *App) Shutdown(ctx context.Context) error

func (*App) Static

func (a *App) Static(prefix, root string, opts ...StaticOption) error

func (*App) StaticFS

func (a *App) StaticFS(prefix string, filesystem fs.FS, opts ...StaticOption) error

func (*App) Trace

func (a *App) Trace(path string, handlers ...HandlerFunc) error

func (*App) URL added in v0.1.0

func (a *App) URL(name string, params ...string) (string, error)

func (*App) Use

func (a *App) Use(handlers ...HandlerFunc)

func (*App) UsePrefix

func (a *App) UsePrefix(prefix string, handlers ...HandlerFunc)

type Bind added in v0.1.1

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

func (*Bind) All added in v0.1.1

func (b *Bind) All(v any) error

func (*Bind) Body added in v0.1.1

func (b *Bind) Body(v any) error

func (*Bind) Form added in v0.1.1

func (b *Bind) Form(v any) error

func (*Bind) Header added in v0.1.1

func (b *Bind) Header(v any) error

func (*Bind) JSON added in v0.1.1

func (b *Bind) JSON(v any) error

func (*Bind) Path added in v0.1.1

func (b *Bind) Path(v any) error

func (*Bind) Query added in v0.1.1

func (b *Bind) Query(v any) error

func (*Bind) TOML added in v0.1.1

func (b *Bind) TOML(v any) error

func (*Bind) Text added in v0.1.1

func (b *Bind) Text(v any) error

func (*Bind) XML added in v0.1.1

func (b *Bind) XML(v any) error

func (*Bind) YAML added in v0.1.1

func (b *Bind) YAML(v any) error

type BindError added in v0.1.0

type BindError struct {
	Source string
	Field  string
	Err    error
}

func (*BindError) Error added in v0.1.0

func (e *BindError) Error() string

func (*BindError) Unwrap added in v0.1.0

func (e *BindError) Unwrap() error

type Config

type Config struct {
	ServerHeader string

	CaseSensitive          bool
	StrictRouting          bool
	AutoHead               bool
	AutoOptions            bool
	HandleMethodNotAllowed bool

	BodyLimit    int64
	ReadTimeout  time.Duration
	WriteTimeout time.Duration
	IdleTimeout  time.Duration

	ProxyHeader    string
	TrustedProxies []string

	RequestBinder RequestBinder
	Validator     Validator
	Renderer      Renderer
	JSONCodec     JSONCodec
	ErrorHandler  ErrorHandler

	RouteCacheSize int
}

Config holds the application and server configuration.

type Context

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

func NewContext

func NewContext(w http.ResponseWriter, r *http.Request) *Context

func (*Context) AbortWithJSON added in v0.1.0

func (c *Context) AbortWithJSON(code int, v any) error

func (*Context) AbortWithStatus added in v0.1.0

func (c *Context) AbortWithStatus(code int) error

func (*Context) Accepts added in v0.1.2

func (c *Context) Accepts(types ...string) string

func (*Context) AppendHeader

func (c *Context) AppendHeader(key string, values ...string) *Context

func (*Context) Attachment

func (c *Context) Attachment(filePath string, name ...string) error

func (*Context) Bind

func (c *Context) Bind() *Bind

func (*Context) Blob added in v0.1.2

func (c *Context) Blob(status int, contentType string, b []byte) error

func (*Context) BodyBytes

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

func (*Context) BodyString

func (c *Context) BodyString() (string, error)

func (*Context) ClearCookie

func (c *Context) ClearCookie(names ...string)

func (*Context) ContentType added in v0.1.2

func (c *Context) ContentType() string

func (*Context) Context

func (c *Context) Context() stdctx.Context

func (*Context) Cookie

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

func (*Context) Cookies

func (c *Context) Cookies() []*http.Cookie

func (*Context) Copy added in v0.1.0

func (c *Context) Copy() *Context

func (*Context) Data

func (c *Context) Data(contentType string, b []byte) error

func (*Context) Download

func (c *Context) Download(filePath string, name ...string) error

func (*Context) Error added in v0.0.73

func (c *Context) Error(err error)

func (*Context) Fail added in v0.1.0

func (c *Context) Fail(err error) error

func (*Context) File

func (c *Context) File(filePath string) error

func (*Context) FileFS

func (c *Context) FileFS(filePath string, filesystem fs.FS) error

func (*Context) FormFile

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

func (*Context) FormFiles

func (c *Context) FormFiles(name string) ([]*multipart.FileHeader, error)

func (*Context) FormValue

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

func (*Context) FullPath

func (c *Context) FullPath() string

func (*Context) Get

func (c *Context) Get(key any) (any, bool)

func (*Context) GetBool added in v0.1.2

func (c *Context) GetBool(key any) bool

func (*Context) GetFloat64 added in v0.1.2

func (c *Context) GetFloat64(key any) float64

func (*Context) GetHeader

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

func (*Context) GetInt added in v0.1.2

func (c *Context) GetInt(key any) int

func (*Context) GetInt64 added in v0.1.2

func (c *Context) GetInt64(key any) int64

func (*Context) GetString added in v0.1.2

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

func (*Context) GetStringMap added in v0.1.2

func (c *Context) GetStringMap(key any) map[string]any

func (*Context) GetStringMapString added in v0.1.2

func (c *Context) GetStringMapString(key any) map[string]string

func (*Context) GetStringMapStringSlice added in v0.1.2

func (c *Context) GetStringMapStringSlice(key any) map[string][]string

func (*Context) GetStringSlice added in v0.1.2

func (c *Context) GetStringSlice(key any) []string

func (*Context) HTML

func (c *Context) HTML(data string) error

func (*Context) HTMLBlob added in v0.1.2

func (c *Context) HTMLBlob(status int, b []byte) error

func (*Context) IP

func (c *Context) IP() string

func (*Context) IPs

func (c *Context) IPs() []string

func (*Context) Inline added in v0.1.2

func (c *Context) Inline(filePath string, name ...string) error

func (*Context) IsPreflight

func (c *Context) IsPreflight() bool

func (*Context) IsWebSocket

func (c *Context) IsWebSocket() bool

func (*Context) JSON

func (c *Context) JSON(v any) error

func (*Context) JSONBlob added in v0.1.2

func (c *Context) JSONBlob(status int, b []byte) error

func (*Context) JSONPretty

func (c *Context) JSONPretty(v any, indent string) error

func (*Context) LastError added in v0.0.73

func (c *Context) LastError() error

func (*Context) Location

func (c *Context) Location(location string) *Context

func (*Context) Method

func (c *Context) Method() string

func (*Context) MultipartForm

func (c *Context) MultipartForm() (*multipart.Form, error)

func (*Context) MustGet

func (c *Context) MustGet(key any) any

func (*Context) Negotiate added in v0.1.2

func (c *Context) Negotiate(status int, offers map[string]any) error

func (*Context) Next

func (c *Context) Next() error

func (*Context) NoContent

func (c *Context) NoContent() error

func (*Context) OriginalURL

func (c *Context) OriginalURL() string

func (*Context) Param

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

func (*Context) ParamOr

func (c *Context) ParamOr(name, fallback string) string

func (*Context) Path

func (c *Context) Path() string

func (*Context) PostForm added in v0.1.2

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

func (*Context) PostFormArray added in v0.1.2

func (c *Context) PostFormArray(name string) []string

func (*Context) PostFormMap added in v0.1.2

func (c *Context) PostFormMap(name string) map[string]string

func (*Context) PostFormOr added in v0.1.2

func (c *Context) PostFormOr(name, fallback string) string

func (*Context) Query

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

func (*Context) QueryArray added in v0.1.2

func (c *Context) QueryArray(name string) []string

func (*Context) QueryMap added in v0.1.2

func (c *Context) QueryMap(name string) map[string]string

func (*Context) QueryOr

func (c *Context) QueryOr(name, fallback string) string

func (*Context) QueryValues

func (c *Context) QueryValues() url.Values

func (*Context) Redirect

func (c *Context) Redirect(code int, location string) error

func (*Context) RemoteIP

func (c *Context) RemoteIP() string

func (*Context) Render

func (c *Context) Render(name string, data any) error

func (*Context) Request

func (c *Context) Request() *http.Request

func (*Context) RequestID

func (c *Context) RequestID() string

func (*Context) Route

func (c *Context) Route() RouteInfo

func (*Context) SSE added in v0.0.71

func (c *Context) SSE(event SSEvent) error

func (*Context) SaveFile

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

func (*Context) Scheme

func (c *Context) Scheme() string

func (*Context) Secure

func (c *Context) Secure() bool

func (*Context) Send

func (c *Context) Send(data any) error

func (*Context) Set

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

func (*Context) SetContext

func (c *Context) SetContext(ctx stdctx.Context)

func (*Context) SetCookie

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

func (*Context) SetHeader

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

func (*Context) SetPath

func (c *Context) SetPath(path string)

func (*Context) SetRequest

func (c *Context) SetRequest(r *http.Request)

func (*Context) SetSameSite added in v0.1.2

func (c *Context) SetSameSite(mode http.SameSite) *Context

func (*Context) SetWriter

func (c *Context) SetWriter(w http.ResponseWriter)

func (*Context) Status

func (c *Context) Status(code int) *Context

func (*Context) Stream

func (c *Context) Stream(contentType string, r io.Reader) error

func (*Context) String

func (c *Context) String(data string) error

func (*Context) TOML added in v0.1.0

func (c *Context) TOML(v any) error

func (*Context) Type

func (c *Context) Type(ext string) *Context

func (*Context) Validate

func (c *Context) Validate(v any) error

func (*Context) Vary

func (c *Context) Vary(fields ...string) *Context

func (*Context) Writer

func (c *Context) Writer() http.ResponseWriter

func (*Context) XML

func (c *Context) XML(v any) error

func (*Context) XMLBlob added in v0.1.2

func (c *Context) XMLBlob(status int, b []byte) error

func (*Context) YAML added in v0.1.0

func (c *Context) YAML(v any) error

type ErrorHandler

type ErrorHandler func(*Context, error)

ErrorHandler handles an error returned from a Zinc handler.

type Group

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

func NewGroup

func NewGroup(app *App, prefix string, handlers ...HandlerFunc) *Group

func (*Group) Add

func (g *Group) Add(method, routePath string, handlers ...HandlerFunc) error

func (*Group) All

func (g *Group) All(path string, handlers ...HandlerFunc) error

func (*Group) Any

func (g *Group) Any(path string, handlers ...HandlerFunc) error

func (*Group) Connect

func (g *Group) Connect(path string, handlers ...HandlerFunc) error

func (*Group) Delete

func (g *Group) Delete(path string, handlers ...HandlerFunc) error

func (*Group) File

func (g *Group) File(routePath, file string) error

func (*Group) FileFS

func (g *Group) FileFS(routePath, file string, filesystem fs.FS) error

func (*Group) Get

func (g *Group) Get(path string, handlers ...any) error

func (*Group) Group

func (g *Group) Group(prefix string, handlers ...HandlerFunc) *Group

func (*Group) Handle added in v0.1.0

func (g *Group) Handle(spec RouteSpec) error

func (*Group) Head

func (g *Group) Head(path string, handlers ...HandlerFunc) error

func (*Group) Match

func (g *Group) Match(methods []string, routePath string, handlers ...HandlerFunc) error

func (*Group) Mount

func (g *Group) Mount(prefix string, h http.Handler)

func (*Group) Options

func (g *Group) Options(path string, handlers ...HandlerFunc) error

func (*Group) Patch

func (g *Group) Patch(path string, handlers ...HandlerFunc) error

func (*Group) Post

func (g *Group) Post(path string, handlers ...HandlerFunc) error

func (*Group) Put

func (g *Group) Put(path string, handlers ...HandlerFunc) error

func (*Group) Route

func (g *Group) Route(prefix string, fn func(*Group), handlers ...HandlerFunc) *Group

func (*Group) RouteNotFound added in v0.1.0

func (g *Group) RouteNotFound(routePath string, handlers ...HandlerFunc) error

func (*Group) Static

func (g *Group) Static(prefix, root string, opts ...StaticOption) error

func (*Group) StaticFS

func (g *Group) StaticFS(prefix string, filesystem fs.FS, opts ...StaticOption) error

func (*Group) Trace

func (g *Group) Trace(path string, handlers ...HandlerFunc) error

func (*Group) Use

func (g *Group) Use(handlers ...HandlerFunc) *Group

type HTTPError

type HTTPError struct {
	Code    int
	Message string
	Cause   error
	Meta    Map
	Headers http.Header
}

HTTPError represents an HTTP error with a status code and optional message.

func NewError

func NewError(code int) *HTTPError

func (*HTTPError) Error

func (e *HTTPError) Error() string

func (*HTTPError) Unwrap added in v0.1.0

func (e *HTTPError) Unwrap() error

func (*HTTPError) WithCause added in v0.1.0

func (e *HTTPError) WithCause(cause error) *HTTPError

func (*HTTPError) WithHeader added in v0.1.0

func (e *HTTPError) WithHeader(key, value string) *HTTPError

func (*HTTPError) WithMessage

func (e *HTTPError) WithMessage(message string) *HTTPError

func (*HTTPError) WithMeta added in v0.1.0

func (e *HTTPError) WithMeta(key string, value any) *HTTPError

type HandlerFunc

type HandlerFunc func(*Context) error

func StringHandler

func StringHandler(str string) HandlerFunc

func Wrap

func Wrap(h http.Handler) HandlerFunc

func WrapFunc

func WrapFunc(fn http.HandlerFunc) HandlerFunc

type JSONCodec

type JSONCodec interface {
	Encode(w io.Writer, v any, indent string) error
	Decode(r io.Reader, v any) error
}

type Map

type Map map[string]any

type Middleware

type Middleware = HandlerFunc

type Renderer

type Renderer interface {
	Render(w io.Writer, name string, data any, c *Context) error
}

type RequestBinder added in v0.1.1

type RequestBinder interface {
	Bind(*Context, any) error
	BindBody(*Context, any) error
	BindQuery(*Context, any) error
	BindForm(*Context, any) error
	BindHeader(*Context, any) error
	BindPath(*Context, any) error
}

type ResponseWriter added in v0.1.2

type ResponseWriter interface {
	http.ResponseWriter
	Status() int
	BytesWritten() int
	Written() bool
}

func WrapResponseWriter added in v0.1.2

func WrapResponseWriter(w http.ResponseWriter) ResponseWriter

type Route

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

type RouteCache

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

func NewRouteCache

func NewRouteCache(size int) *RouteCache

type RouteHandler

type RouteHandler = HandlerFunc

type RouteHandlerMap

type RouteHandlerMap map[string]HandlerFunc

type RouteInfo

type RouteInfo struct {
	Name    string
	Method  string
	Path    string
	Params  []string
	Mounted bool
	Handler string
}

type RouteMap

type RouteMap map[string]map[string]*Route

type RouteSpec added in v0.1.0

type RouteSpec struct {
	Name    string
	Method  string
	Path    string
	Handler HandlerFunc
}

type Router

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

func (*Router) Add

func (r *Router) Add(method, path string, handlers ...HandlerFunc) error

func (*Router) AddNamed added in v0.1.0

func (r *Router) AddNamed(method, path, name string, handlers ...HandlerFunc) error

func (*Router) Find

func (r *Router) Find(method, path string) (HandlerFunc, *Context)

func (*Router) Routes

func (r *Router) Routes() []RouteInfo

type SSEvent added in v0.1.2

type SSEvent struct {
	Event string
	ID    string
	Retry time.Duration
	Data  any
}

type StaticConfig

type StaticConfig struct {
	Browse bool
	Index  string
}

type StaticOption

type StaticOption func(*StaticConfig)

func WithStaticBrowse

func WithStaticBrowse(browse bool) StaticOption

func WithStaticIndex

func WithStaticIndex(index string) StaticOption

type TemplateExecutor added in v0.0.76

type TemplateExecutor interface {
	ExecuteTemplate(w io.Writer, name string, data any) error
}

type TemplateRenderer added in v0.0.76

type TemplateRenderer struct {
	Engine TemplateExecutor
	// contains filtered or unexported fields
}

func NewHTMLTemplateRenderer added in v0.0.76

func NewHTMLTemplateRenderer(engine *htmltemplate.Template, opts ...TemplateRendererOption) *TemplateRenderer

func NewTemplateRenderer added in v0.0.76

func NewTemplateRenderer(engine TemplateExecutor, opts ...TemplateRendererOption) *TemplateRenderer

func NewTextTemplateRenderer added in v0.0.76

func NewTextTemplateRenderer(engine *texttemplate.Template, opts ...TemplateRendererOption) *TemplateRenderer

func (*TemplateRenderer) Render added in v0.0.76

func (r *TemplateRenderer) Render(w io.Writer, name string, data any, _ *Context) error

type TemplateRendererOption added in v0.0.76

type TemplateRendererOption func(*TemplateRenderer)

func WithTemplateSuffixes added in v0.0.76

func WithTemplateSuffixes(suffixes ...string) TemplateRendererOption

type Validator

type Validator interface {
	Validate(any) error
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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