Documentation
¶
Overview ¶
Package zen is a lightweight, high-performance HTTP microframework built on net/http with a custom radix tree router.
Quick Start ¶
r := zen.New(":8080")
r.GET("/hello", func(c *zen.Ctx) {
c.String(200, "Hello, World!")
})
r.Run()
Middleware ¶
Zen supports both global and per-route middleware:
r.Use(middleware.Recover) r.Use(middleware.Logger)
Routing ¶
Routes use Go 1.22+ patterns with path parameters:
r.GET("/users/{id}", getUser)
r.POST("/users", createUser)
r.PUT("/users/{id}", updateUser)
r.DELETE("/users/{id}", deleteUser)
Route Groups ¶
api := r.Group("/api")
api.HandleRaw("GET /health", healthCheck)
Binding and Validation ¶
var req CreateUserRequest
if err := c.BindJSON(&req); err != nil {
c.Error(400, "invalid request")
return
}
if err := zen.Validate(&req); err != nil {
c.Error(400, err.Error())
return
}
Context and Lifecycle ¶
A zen.Ctx is created per request via sync.Pool and released back after the request completes. The hot path avoids context.WithValue entirely; FromRequest is only needed for interop with standard http.Handler patterns.
Performance ¶
Zen is designed for zero-allocation middleware chains, pooled Ctx and streaming JSON/XML encoding.
Index ¶
- Variables
- func BytesToString(b []byte) string
- func DefaultValidator() *validator.Validate
- func EnableAutoValidation()
- func SetValidator(v Validator)
- func StringToBytes(s string) []byte
- func Validate(dest any) error
- type Config
- type Ctx
- func (c *Ctx) Attachment(filePath, attachmentName string)
- func (c *Ctx) Bind(dest any) error
- func (c *Ctx) BindBody(dest any) error
- func (c *Ctx) BindForm(dest any) error
- func (c *Ctx) BindHeader(dest any) error
- func (c *Ctx) BindJSON(dest any) error
- func (c *Ctx) BindPathParams(dest any) error
- func (c *Ctx) BindQueryParams(dest any) error
- func (c *Ctx) BindXML(dest any) error
- func (c *Ctx) Blob(status int, contentType string, data []byte)
- func (c *Ctx) Body() ([]byte, error)
- func (c *Ctx) Copy() *Ctx
- func (c *Ctx) Error(status int, message string)
- func (c *Ctx) File(filePath string)
- func (c *Ctx) FormFile(fieldName string) (*multipart.FileHeader, multipart.File, error)
- func (c *Ctx) FormFiles(fieldName string) ([]*multipart.FileHeader, error)
- func (c *Ctx) Get(key string) (any, bool)
- func (c *Ctx) HTML(status int, html string)
- func (c *Ctx) Header(key string) string
- func (c *Ctx) Inline(filePath string)
- func (c *Ctx) JSON(status int, data any)
- func (c *Ctx) Keys() map[string]any
- func (c *Ctx) Next()
- func (c *Ctx) Param(key string) string
- func (c *Ctx) QueryParam(key string) string
- func (c *Ctx) ReadFile(fieldName string) (header *multipart.FileHeader, content []byte, err error)
- func (c *Ctx) Redirect(status int, location string)
- func (c *Ctx) SSEvent(event string, data any) error
- func (c *Ctx) Set(key string, val any)
- func (c *Ctx) Status(status int)
- func (c *Ctx) Stream(status int, contentType string, body io.Reader) error
- func (c *Ctx) String(status int, text string)
- func (c *Ctx) XML(status int, data any)
- type Engine
- type FormError
- type HandlerFunc
- type RouterGroup
- func (g *RouterGroup) DELETE(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) GET(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) Group(prefix string, middleware ...HandlerFunc) *RouterGroup
- func (g *RouterGroup) HEAD(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) HandleRaw(pattern string, handler http.Handler)
- func (g *RouterGroup) OPTIONS(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) PATCH(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) POST(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) PUT(path string, handlers ...HandlerFunc)
- func (g *RouterGroup) Prefix() string
- func (g *RouterGroup) Use(middleware ...HandlerFunc)
- type SkipFunc
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ErrFlusherUnsupported = errors.New("sse: SSE requires http.Flusher")
ErrFlusherUnsupported is returned by SSEvent when the ResponseWriter does not implement http.Flusher.
var ErrInvalidBindTarget = errors.New("http: BindForm dest must be a pointer to a struct")
ErrInvalidBindTarget is returned by BindForm when dest is not a pointer to a struct.
Functions ¶
func BytesToString ¶ added in v1.2.0
BytesToString converts a byte slice to a string without allocations.
func DefaultValidator ¶ added in v1.2.0
DefaultValidator returns the underlying go-playground/validator/v10 instance when using the default built-in validator, or nil if a custom validator is set. Use this to register custom validation tags:
zen.DefaultValidator().RegisterValidation("is-even", func(fl validator.FieldLevel) bool {
return fl.Field().Int()%2 == 0
})
func EnableAutoValidation ¶ added in v1.3.0
func EnableAutoValidation()
EnableAutoValidation enables automatic Validate() calls after BindJSON, BindXML, and BindForm.
func SetValidator ¶ added in v1.2.0
func SetValidator(v Validator)
SetValidator sets a custom validator for request validation. Pass nil to disable validation entirely.
func StringToBytes ¶ added in v1.2.0
StringToBytes converts a string to a byte slice without allocations. The returned bytes MUST NOT be modified.
Types ¶
type Config ¶ added in v1.2.0
type Config struct {
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
ReadHeaderTimeout time.Duration
MaxHeaderBytes int
ShutdownTimeout time.Duration
}
Config holds server-level timeout and header size settings. Use DefaultConfig to obtain sensible defaults, then override fields as needed.
func DefaultConfig ¶ added in v1.2.0
func DefaultConfig() Config
DefaultConfig returns a Config with standard timeout and buffer values. Timeouts and MaxHeaderBytes default to 0 to bypass the Go standard library's tracking loops, matching raw net/http performance baselines.
type Ctx ¶ added in v1.2.0
type Ctx struct {
Response http.ResponseWriter
Request *http.Request
// contains filtered or unexported fields
}
Ctx is the per-request context container for zen handlers and middleware components. Valid ONLY for the explicit lifetime of the request—never preserve references beyond handler returns.
func FromContext ¶ added in v1.2.0
FromContext extracts a Ctx from a context.Context.
func FromRequest ¶
FromRequest extracts a Ctx from an http.Request.
func (*Ctx) Attachment ¶ added in v1.2.0
Attachment sends the requested file as a downloadable attachment. The Content-Disposition header is set with the provided attachment name. If attachmentName is empty, the file base name is used.
Example:
c.Attachment("/tmp/report.pdf", "monthly-report.pdf")
func (*Ctx) Bind ¶ added in v1.2.0
Bind auto-detects the request content type and decodes the payload into dest. For GET, DELETE, and HEAD requests, it automatically populates query parameters first.
func (*Ctx) BindBody ¶ added in v1.2.0
BindBody parses the request body into dest based on the Content-Type header, completely skipping path and query parameters.
func (*Ctx) BindForm ¶ added in v1.2.0
BindForm parses URL-encoded or multipart form data into a struct.
Automatically runs struct validation after binding unless validation was explicitly disabled via the setup configuration.
Example:
type LoginForm struct {
Email string `form:"email" validate:"required,email"`
Password string `form:"password" validate:"required,min=8"`
}
func (*Ctx) BindHeader ¶ added in v1.2.0
BindHeader binds HTTP request headers to a struct using `header` or `json` tags. Header names are canonicalized via http.CanonicalHeaderKey at compile time.
Example:
type Headers struct {
UserID string `header:"X-User-Id"`
APIKey string `header:"X-Api-Key"`
Rate int `header:"X-Rate-Limit"`
}
func (*Ctx) BindJSON ¶ added in v1.2.0
BindJSON parses the request body as JSON and decodes it into dest. Uses json.NewDecoder which streams directly from the request body, avoiding intermediate byte slice allocations.
Automatically runs struct validation after decode if a Validator is configured.
func (*Ctx) BindPathParams ¶ added in v1.2.0
BindPathParams extracts route wildcards using native Go 1.22+ request context maps.
func (*Ctx) BindQueryParams ¶ added in v1.2.0
BindQueryParams parses query parameters into dest struct fields.
func (*Ctx) BindXML ¶ added in v1.2.0
BindXML parses the request body as XML and decodes it into dest. Uses xml.NewDecoder which streams directly from the request body.
Automatically runs struct validation after decode if a Validator is configured.
Returns an error if the body is not valid XML, cannot be decoded, or struct validation fails.
Example:
var req CreateUserRequest
if err := c.BindXML(&req); err != nil {
c.Error(http.StatusBadRequest, err.Error())
return
}
func (*Ctx) Blob ¶ added in v1.2.0
Blob writes a byte slice as the response body with the given content type. The response Content-Type is set to the provided MIME type. Write errors are logged but not returned (they indicate connection issues).
Example:
data := []byte("id,name\n1,John Doe")
c.Blob(http.StatusOK, "text/csv", data)
func (*Ctx) Body ¶ added in v1.2.0
Body reads and returns the complete raw request body as a byte slice. It is the caller's responsibility to interpret the bytes.
func (*Ctx) Error ¶ added in v1.2.0
Error writes a plain text error message to the response with the given HTTP status. Unlike JSON(), this sends plain text without JSON encoding, similar to http.Error(). The response Content-Type header is set to "text/plain; charset=utf-8".
This is the preferred method for simple error responses where JSON structure is not needed. For structured error responses, use JSON() with a plain map or custom struct.
Example:
c.Error(http.StatusBadRequest, "invalid email format")
func (*Ctx) File ¶ added in v1.2.0
File sends the requested file as the HTTP response body. The content type is inferred automatically and errors are handled by http.ServeFile.
Example:
c.File("/tmp/report.pdf")
func (*Ctx) FormFile ¶ added in v1.2.0
FormFile retrieves a single file from a multipart form upload. Returns the file header and a file handle for streaming. The caller is responsible for closing the file.
Example:
header, file, err := c.FormFile("avatar")
if err != nil {
c.Error(http.StatusBadRequest, err.Error())
return
}
defer file.Close()
func (*Ctx) FormFiles ¶ added in v1.2.0
func (c *Ctx) FormFiles(fieldName string) ([]*multipart.FileHeader, error)
FormFiles retrieves all file headers for a multipart form field. The caller opens each file individually for streaming access.
Example:
headers, err := c.FormFiles("attachments")
if err != nil {
c.Error(http.StatusBadRequest, err.Error())
return
}
for _, h := range headers {
file, _ := h.Open()
defer file.Close()
}
func (*Ctx) HTML ¶ added in v1.2.0
HTML writes an HTML string directly to the response with the given HTTP status. The response Content-Type header is automatically set to "text/html; charset=utf-8".
Write errors are logged but not returned (they indicate connection issues).
Example:
c.HTML(http.StatusOK, "<h1>Hello World</h1>")
func (*Ctx) Header ¶ added in v1.2.0
Header returns the value of a request header by key. Returns an empty string if the header is not present.
Example:
token := c.Header("Authorization") // "Bearer <token>"
func (*Ctx) Inline ¶ added in v1.2.0
Inline sends the requested file to be displayed inline by the browser. The Content-Disposition header is set to inline.
Example:
c.Inline("/tmp/image.png")
func (*Ctx) JSON ¶ added in v1.2.0
JSON encodes data as JSON and streams it straight to the response writer.
Sets the "Content-Type" header to "application/json" automatically. Write errors are handled and logged safely via internal system loggers.
func (*Ctx) Param ¶ added in v1.2.0
Param returns the URL path parameter for the given key.
Given a route registered as "GET /users/{id}", the handler can retrieve the captured segment with:
id := c.Param("id") // GET /users/42 -> "42"
func (*Ctx) QueryParam ¶ added in v1.2.0
QueryParam returns the first value of a query parameter from the request URL. Returns an empty string if the parameter is not present.
Example:
page := c.QueryParam("page") // GET /posts?page=2 -> "2"
search := c.QueryParam("q") // GET /posts?q=golang-> "golang"
func (*Ctx) ReadFile ¶ added in v1.2.0
ReadFile is a convenience method that reads a single uploaded file into memory. For large files, use FormFile() and stream the content instead.
func (*Ctx) Redirect ¶ added in v1.2.0
Redirect sends an HTTP redirect to the specified location. It sets the Location header and writes the provided redirect status.
Example:
c.Redirect(http.StatusMovedPermanently, "https://example.com/new")
func (*Ctx) SSEvent ¶ added in v1.2.0
SSEvent writes a Server-Sent Event to the client. It sets required SSE headers and flushes the response.
func (*Ctx) Set ¶ added in v1.2.0
Set stores a value in the context. The internal map is allocated on first use.
func (*Ctx) Status ¶ added in v1.2.0
Status writes a response header with no-body and the given HTTP status.
Example:
c.Status(http.StatusNoContent)
func (*Ctx) Stream ¶ added in v1.2.0
Stream copies data from an io.Reader to the response body with the given content type. The response Content-Type is set to the provided MIME type.
Example:
f, err := os.Open("/tmp/image.png")
if err != nil {
return err
}
defer f.Close()
return c.Stream(http.StatusOK, "image/png", f)
func (*Ctx) String ¶ added in v1.2.0
String writes a plain text string directly to the response with the given HTTP status.
Write errors are logged but not returned (they indicate connection issues).
Example:
c.String(http.StatusOK, "Hello World")
func (*Ctx) XML ¶ added in v1.2.0
XML encodes data as XML and writes it to the response with the given HTTP status code. Uses xml.NewEncoder which streams directly to the response writer.
The response Content-Type header is automatically set to "application/xml". Write errors are logged but not returned (they indicate connection issues).
Example:
type Response struct {
XMLName xml.Name `xml:"response"`
Message string `xml:"message"`
}
c.XML(http.StatusOK, Response{Message: "hello"})
type Engine ¶ added in v1.2.0
type Engine struct {
RouterGroup
// contains filtered or unexported fields
}
Engine is the top-level application container. It embeds a root RouterGroup and owns the radix tree router and the http.Server.
func (*Engine) File ¶ added in v1.2.0
File serves a single file at the given path pattern via http.ServeFile.
func (*Engine) Run ¶ added in v1.2.0
func (e *Engine) Run()
Run starts the HTTP server and blocks until a shutdown signal is received.
func (*Engine) RunTLS ¶ added in v1.2.0
RunTLS starts the HTTPS server with the given certificate and key files, and blocks until a shutdown signal is received.
func (*Engine) ServeHTTP ¶ added in v1.2.0
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements the http.Handler interface using the radix tree router.
type FormError ¶
FormError is returned by BindForm when a form value cannot be parsed into the target field's type (e.g., "abc" into an int field).
type HandlerFunc ¶ added in v1.2.0
type HandlerFunc func(*Ctx)
HandlerFunc is the universal type for both route handlers and middleware.
type RouterGroup ¶ added in v1.2.0
type RouterGroup struct {
// contains filtered or unexported fields
}
RouterGroup groups routes under a common prefix with optional shared middleware. An Engine embeds a root RouterGroup; Group creates child groups.
func (*RouterGroup) DELETE ¶ added in v1.2.0
func (g *RouterGroup) DELETE(path string, handlers ...HandlerFunc)
DELETE registers a handler for the DELETE method.
func (*RouterGroup) GET ¶ added in v1.2.0
func (g *RouterGroup) GET(path string, handlers ...HandlerFunc)
GET registers a handler for the GET method. The final element in handlers is the main handler; preceding elements are middleware.
func (*RouterGroup) Group ¶ added in v1.2.0
func (g *RouterGroup) Group(prefix string, middleware ...HandlerFunc) *RouterGroup
Group creates a child group with an additional path prefix and optional middleware. The child group inherits all parent middleware and appends the new middleware after it. Uses a single upfront allocation to prevent double-allocation slice resizes.
func (*RouterGroup) HEAD ¶ added in v1.2.0
func (g *RouterGroup) HEAD(path string, handlers ...HandlerFunc)
HEAD registers a handler for the HEAD method.
func (*RouterGroup) HandleRaw ¶ added in v1.2.0
func (g *RouterGroup) HandleRaw(pattern string, handler http.Handler)
HandleRaw registers a raw http.Handler on the router using the zen handler chain. The pattern uses Go 1.22+ ServeMux syntax ({param}, {path...}) which is automatically converted to the router's native syntax (:param, *path). The group prefix is prepended to the path automatically.
func (*RouterGroup) OPTIONS ¶ added in v1.2.0
func (g *RouterGroup) OPTIONS(path string, handlers ...HandlerFunc)
OPTIONS registers a handler for the OPTIONS method.
func (*RouterGroup) PATCH ¶ added in v1.2.0
func (g *RouterGroup) PATCH(path string, handlers ...HandlerFunc)
PATCH registers a handler for the PATCH method.
func (*RouterGroup) POST ¶ added in v1.2.0
func (g *RouterGroup) POST(path string, handlers ...HandlerFunc)
POST registers a handler for the POST method.
func (*RouterGroup) PUT ¶ added in v1.2.0
func (g *RouterGroup) PUT(path string, handlers ...HandlerFunc)
PUT registers a handler for the PUT method.
func (*RouterGroup) Prefix ¶ added in v1.2.0
func (g *RouterGroup) Prefix() string
Prefix returns the full path prefix of this group.
func (*RouterGroup) Use ¶ added in v1.2.0
func (g *RouterGroup) Use(middleware ...HandlerFunc)
Use appends middleware to the group. Middleware runs for every route registered on this group.
type SkipFunc ¶ added in v1.2.0
SkipFunc decides whether a request should bypass middleware (auth, body limit, etc). It receives the current request and returns true for routes to skip.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package auth provides authentication and authorization middleware (JWT, OAuth2, OIDC, Basic, RBAC, ABAC, PBAC, session).
|
Package auth provides authentication and authorization middleware (JWT, OAuth2, OIDC, Basic, RBAC, ABAC, PBAC, session). |
|
Package env provides helpers for reading configuration from environment variables.
|
Package env provides helpers for reading configuration from environment variables. |
|
Package logger provides a structured logging facade with slog backend and colored console output.
|
Package logger provides a structured logging facade with slog backend and colored console output. |
|
Package middleware provides built-in HTTP middleware for zen (recovery, logging, CORS, CSRF, compression, rate limiting, body limit, pprof).
|
Package middleware provides built-in HTTP middleware for zen (recovery, logging, CORS, CSRF, compression, rate limiting, body limit, pprof). |
|
Package openapi generates OpenAPI 3.0.3 specifications and serves the Swagger UI for zen routes.
|
Package openapi generates OpenAPI 3.0.3 specifications and serves the Swagger UI for zen routes. |
|
Package system provides build-time metadata (version, banner) for the zen framework.
|
Package system provides build-time metadata (version, banner) for the zen framework. |