Documentation
¶
Overview ¶
Package httpx is nexus's router-agnostic HTTP seam.
Historically nexus bound directly to gin: endpoint chains were []gin.HandlerFunc, flow control was gin's c.Next()/c.Abort(), and routes were mounted on a *gin.Engine. httpx removes that coupling. The framework holds an httpx.Router and every handler/middleware sees an *httpx.Ctx; the concrete router (gin, chi, net/http) lives behind a thin adapter under httpx/ginrouter, httpx/chirouter, httpx/stdrouter.
The pivotal design choice: chain execution lives HERE, not in the router. *Ctx owns the handler slice, the index, and Next()/Abort() — gin's exact semantics, reimplemented once. An adapter therefore only matches a path and returns its params; it never runs middleware. That is what lets the same middleware run unchanged on any backend.
Canonical route syntax is gin's (":id", "*rest"); chi/std adapters translate on registration so existing nexus route strings need no rewrite.
Index ¶
- Variables
- func Serve(chain []HandlerFunc, w http.ResponseWriter, r *http.Request, route string, ...)
- func WildcardName(path string) string
- type Ctx
- func (c *Ctx) Abort()
- func (c *Ctx) AbortWithStatus(status int)
- func (c *Ctx) AbortWithStatusJSON(status int, body any)
- func (c *Ctx) BindJSON(ptr any) error
- func (c *Ctx) ClientIP() string
- func (c *Ctx) Context() context.Context
- func (c *Ctx) Cookie(name string) (string, error)
- func (c *Ctx) Data(status int, contentType string, b []byte)
- func (c *Ctx) DefaultPostForm(key, def string) string
- func (c *Ctx) DefaultQuery(key, def string) string
- func (c *Ctx) Error(err error) error
- func (c *Ctx) Errors() []error
- func (c *Ctx) ErrorsString() string
- func (c *Ctx) FileFromFS(filepath string, fs http.FileSystem)
- func (c *Ctx) FormFile(name string) (*multipart.FileHeader, error)
- func (c *Ctx) FullPath() string
- func (c *Ctx) Get(key string) (any, bool)
- func (c *Ctx) GetHeader(key string) string
- func (c *Ctx) GetPostForm(key string) (string, bool)
- func (c *Ctx) Header(key, val string)
- func (c *Ctx) IsAborted() bool
- func (c *Ctx) JSON(status int, body any)
- func (c *Ctx) LastError() error
- func (c *Ctx) Method() string
- func (c *Ctx) MultipartForm() (*multipart.Form, error)
- func (c *Ctx) Next()
- func (c *Ctx) Param(key string) string
- func (c *Ctx) Path() string
- func (c *Ctx) PostForm(key string) string
- func (c *Ctx) PostFormArray(key string) []string
- func (c *Ctx) Query(key string) string
- func (c *Ctx) Redirect(status int, location string)
- func (c *Ctx) RemoteIP() string
- func (c *Ctx) SaveUploadedFile(file *multipart.FileHeader, dst string) error
- func (c *Ctx) Set(key string, val any)
- func (c *Ctx) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
- func (c *Ctx) SetRequestContext(ctx context.Context)
- func (c *Ctx) SetSameSite(s http.SameSite)
- func (c *Ctx) ShouldBind(ptr any) error
- func (c *Ctx) ShouldBindHeader(ptr any) error
- func (c *Ctx) ShouldBindJSON(ptr any) error
- func (c *Ctx) ShouldBindQuery(ptr any) error
- func (c *Ctx) ShouldBindUri(ptr any) error
- func (c *Ctx) Status(code int)
- func (c *Ctx) String(status int, s string)
- func (c *Ctx) Stringf(status int, format string, args ...any)
- func (c *Ctx) Written() bool
- type Group
- type H
- type HandlerFunc
- type ResponseWriter
- type RouteInfo
- type Router
Constants ¶
This section is empty.
Variables ¶
var StdMethods = []string{"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"}
StdMethods is the set Any mounts over.
Functions ¶
func Serve ¶
func Serve(chain []HandlerFunc, w http.ResponseWriter, r *http.Request, route string, param func(string) string)
Serve is the single per-request entry every adapter calls: build a Ctx over the backend's writer/request/param-getter and run the chain. By the time we get here the router has done its only job — match + params.
func WildcardName ¶ added in v1.20.4
WildcardName returns the name of the trailing wildcard segment in a canonical route path ("/assets/*filepath" -> "filepath"), or "" when the path has no wildcard. Router adapters use it to normalize the wildcard param value to gin's convention — a leading-slash suffix (gin's c.Param("filepath") for /assets/app.js is "/app.js") — on every backend, so handlers that build paths like "assets"+c.Param("filepath") behave identically on gin, chi, and stdlib.
Types ¶
type Ctx ¶
type Ctx struct {
Writer *ResponseWriter
Request *http.Request
// contains filtered or unexported fields
}
Ctx is the transport-neutral request handle — the union of the gin.Context surface nexus actually used, with no router type in its API.
func NewCtx ¶
NewCtx builds a standalone Ctx over a writer/request — for tests and for callers that have an http.ResponseWriter + *http.Request and want the neutral handle without a router (no chain; Next is a no-op). Optional param resolves path params.
func (*Ctx) Abort ¶
func (c *Ctx) Abort()
Abort stops the chain after the current handler (gin semantics).
func (*Ctx) AbortWithStatus ¶
AbortWithStatus / AbortWithStatusJSON mirror gin's abort helpers.
func (*Ctx) AbortWithStatusJSON ¶
func (*Ctx) BindJSON ¶
BindJSON decodes JSON and, on error, writes a 400 + aborts (gin's c.BindJSON).
func (*Ctx) ClientIP ¶
ClientIP returns a best-effort client IP (X-Forwarded-For / X-Real-IP / RemoteAddr). The framework's trusted-proxy policy lives in middleware.ClientIP; this is the simple default used when a Ctx is asked directly.
func (*Ctx) DefaultPostForm ¶ added in v1.20.1
DefaultPostForm returns the form value for key, or def when it is absent (gin's c.DefaultPostForm).
func (*Ctx) DefaultQuery ¶
func (*Ctx) Error ¶
Error accumulates a handler error (gin's c.Error) and returns it, so callers can keep gin's `_ = c.Error(err)` form. metrics/trace read these after Next() to record failures.
func (*Ctx) ErrorsString ¶
ErrorsString joins accumulated errors (replaces gin's c.Errors.String()).
func (*Ctx) FileFromFS ¶
func (c *Ctx) FileFromFS(filepath string, fs http.FileSystem)
FileFromFS serves a single file from an http.FileSystem (gin's c.FileFromFS).
func (*Ctx) FormFile ¶ added in v1.20.1
func (c *Ctx) FormFile(name string) (*multipart.FileHeader, error)
FormFile returns the first uploaded file for the named multipart form key (gin's c.FormFile).
func (*Ctx) GetPostForm ¶ added in v1.20.1
GetPostForm returns the first form value for key and whether it was present (gin's c.GetPostForm) — present-but-empty reports ok=true.
func (*Ctx) Header ¶
Header sets a response header (gin's c.Header). With an empty value it deletes the header, matching gin.
func (*Ctx) LastError ¶
LastError returns the most recent accumulated error, or nil (replaces gin's c.Errors.Last().Err).
func (*Ctx) MultipartForm ¶ added in v1.20.1
MultipartForm parses and returns the full multipart form (gin's c.MultipartForm).
func (*Ctx) Next ¶
func (c *Ctx) Next()
Next runs the remaining handlers. Mirrors gin's loop so a recovery middleware's `defer recover(); c.Next()` still catches downstream panics.
func (*Ctx) PostForm ¶ added in v1.20.1
PostForm returns the first value for the named POST/PUT body form key, or "" if absent (gin's c.PostForm).
func (*Ctx) PostFormArray ¶ added in v1.20.1
PostFormArray returns all values for a repeated form key (gin's c.PostFormArray).
func (*Ctx) RemoteIP ¶
RemoteIP returns the actual TCP peer IP (host part of RemoteAddr), ignoring X-Forwarded-For — unspoofable, for security gates. Mirrors gin's c.RemoteIP().
func (*Ctx) SaveUploadedFile ¶ added in v1.20.1
func (c *Ctx) SaveUploadedFile(file *multipart.FileHeader, dst string) error
SaveUploadedFile writes an uploaded file header to dst on disk (gin's c.SaveUploadedFile).
func (*Ctx) SetRequestContext ¶
SetRequestContext swaps the request's context (the auth/trace pattern of c.Request = c.Request.WithContext(ctx)).
func (*Ctx) SetSameSite ¶
SetSameSite + SetCookie mirror gin's cookie helpers used by auth/cookie.go.
func (*Ctx) ShouldBind ¶
ShouldBind fills fields tagged `form:"name"` from a parsed form body (url-encoded or multipart).
func (*Ctx) ShouldBindHeader ¶
ShouldBindHeader fills fields tagged `header:"Name"` from request headers.
func (*Ctx) ShouldBindJSON ¶
ShouldBindJSON decodes the request body as JSON into ptr.
func (*Ctx) ShouldBindQuery ¶
ShouldBindQuery fills fields tagged `query:"name"` (or `form:"name"`) from the URL query.
func (*Ctx) ShouldBindUri ¶
ShouldBindUri fills fields tagged `uri:"name"` from path params.
func (*Ctx) String ¶
String writes a plain-text body (gin's c.String, simplified: nexus only ever writes a finished string, never a printf format — keeping it non-variadic also avoids vet's format-string check on dynamic bodies).
type Group ¶
type Group interface {
Handle(method, path string, chain ...HandlerFunc)
GET(path string, chain ...HandlerFunc)
POST(path string, chain ...HandlerFunc)
PUT(path string, chain ...HandlerFunc)
DELETE(path string, chain ...HandlerFunc)
PATCH(path string, chain ...HandlerFunc)
OPTIONS(path string, chain ...HandlerFunc)
HEAD(path string, chain ...HandlerFunc)
Any(path string, chain ...HandlerFunc)
Use(mw ...HandlerFunc)
Group(prefix string, mw ...HandlerFunc) Group
Static(prefix, dir string)
}
Group is a sub-router (gin.RouterGroup). Dashboards mount under one.
type HandlerFunc ¶
type HandlerFunc func(*Ctx)
HandlerFunc is the one handler/middleware shape. Middleware calls c.Next() to advance; returning without it (or calling c.Abort()) stops the chain.
type ResponseWriter ¶
type ResponseWriter struct {
http.ResponseWriter
// contains filtered or unexported fields
}
ResponseWriter wraps the backend writer to track status + bytes-written (the framework relies on Written() to avoid clobbering a handler that wrote its own response). It transparently forwards Flush/Hijack so SSE streaming and WebSocket upgrades keep working on any backend.
func (*ResponseWriter) Flush ¶
func (w *ResponseWriter) Flush()
Flush forwards to the backend writer (SSE: ext_devreload streams over this).
func (*ResponseWriter) Hijack ¶
func (w *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
Hijack forwards to the backend writer so gorilla/websocket can upgrade.
func (*ResponseWriter) Status ¶
func (w *ResponseWriter) Status() int
Status reports the committed status (200 until set).
func (*ResponseWriter) WriteHeader ¶
func (w *ResponseWriter) WriteHeader(code int)
func (*ResponseWriter) Written ¶
func (w *ResponseWriter) Written() bool
Written reports whether the header/body was started.
type Router ¶
type Router interface {
// Handle mounts a chain at method+path (canonical ":id"/"*rest" syntax).
Handle(method, path string, chain ...HandlerFunc)
// GET/POST/... are method sugar over Handle.
GET(path string, chain ...HandlerFunc)
POST(path string, chain ...HandlerFunc)
PUT(path string, chain ...HandlerFunc)
DELETE(path string, chain ...HandlerFunc)
PATCH(path string, chain ...HandlerFunc)
OPTIONS(path string, chain ...HandlerFunc)
HEAD(path string, chain ...HandlerFunc)
// Any mounts the chain for every standard method (gin's Any).
Any(path string, chain ...HandlerFunc)
// Use appends app-wide middleware applied to routes registered afterward.
Use(mw ...HandlerFunc)
// Group returns a sub-router rooted at prefix, carrying mw + parent state.
Group(prefix string, mw ...HandlerFunc) Group
// NoRoute sets the fallback chain (SPA index.html).
NoRoute(chain ...HandlerFunc)
// Static serves a directory under a URL prefix.
Static(prefix, dir string)
// Routes lists mounted routes for the dashboard.
Routes() []RouteInfo
// Run binds and serves (backend's ListenAndServe).
Run(addr string) error
http.Handler
}
Router is the seam every backend implements. The framework never names a concrete router type — it holds this.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package chirouter is an opt-in chi-backed nexus router.
|
Package chirouter is an opt-in chi-backed nexus router. |
|
Package stdrouter is the DEFAULT nexus router: Go 1.22's net/http.ServeMux behind the httpx.Router seam, with zero third-party dependencies.
|
Package stdrouter is the DEFAULT nexus router: Go 1.22's net/http.ServeMux behind the httpx.Router seam, with zero third-party dependencies. |