httpx

package
v1.22.1 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: MIT Imports: 13 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

func WildcardName(path string) string

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

func NewCtx(w http.ResponseWriter, r *http.Request, param ...func(string) string) *Ctx

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

func (c *Ctx) AbortWithStatus(status int)

AbortWithStatus / AbortWithStatusJSON mirror gin's abort helpers.

func (*Ctx) AbortWithStatusJSON

func (c *Ctx) AbortWithStatusJSON(status int, body any)

func (*Ctx) BindJSON

func (c *Ctx) BindJSON(ptr any) error

BindJSON decodes JSON and, on error, writes a 400 + aborts (gin's c.BindJSON).

func (*Ctx) ClientIP

func (c *Ctx) ClientIP() string

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) Context

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

Context returns the request's context (gin's c.Request.Context()).

func (*Ctx) Cookie

func (c *Ctx) Cookie(name string) (string, error)

Cookie reads a request cookie value.

func (*Ctx) Data

func (c *Ctx) Data(status int, contentType string, b []byte)

Data writes a raw body with an explicit content type (gin's c.Data).

func (*Ctx) DefaultPostForm added in v1.20.1

func (c *Ctx) DefaultPostForm(key, def string) string

DefaultPostForm returns the form value for key, or def when it is absent (gin's c.DefaultPostForm).

func (*Ctx) DefaultQuery

func (c *Ctx) DefaultQuery(key, def string) string

func (*Ctx) Error

func (c *Ctx) Error(err error) 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) Errors

func (c *Ctx) Errors() []error

func (*Ctx) ErrorsString

func (c *Ctx) ErrorsString() string

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) FullPath

func (c *Ctx) FullPath() string

func (*Ctx) Get

func (c *Ctx) Get(key string) (any, bool)

func (*Ctx) GetHeader

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

GetHeader reads a request header (gin's c.GetHeader).

func (*Ctx) GetPostForm added in v1.20.1

func (c *Ctx) GetPostForm(key string) (string, bool)

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

func (c *Ctx) Header(key, val string)

Header sets a response header (gin's c.Header). With an empty value it deletes the header, matching gin.

func (*Ctx) IsAborted

func (c *Ctx) IsAborted() bool

func (*Ctx) JSON

func (c *Ctx) JSON(status int, body any)

JSON writes a JSON body with the given status (gin's c.JSON).

func (*Ctx) LastError

func (c *Ctx) LastError() error

LastError returns the most recent accumulated error, or nil (replaces gin's c.Errors.Last().Err).

func (*Ctx) Method

func (c *Ctx) Method() string

func (*Ctx) MultipartForm added in v1.20.1

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

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) Param

func (c *Ctx) Param(key string) string

func (*Ctx) Path

func (c *Ctx) Path() string

func (*Ctx) PostForm added in v1.20.1

func (c *Ctx) PostForm(key string) string

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

func (c *Ctx) PostFormArray(key string) []string

PostFormArray returns all values for a repeated form key (gin's c.PostFormArray).

func (*Ctx) Query

func (c *Ctx) Query(key string) string

func (*Ctx) Redirect

func (c *Ctx) Redirect(status int, location string)

Redirect issues an HTTP redirect (gin's c.Redirect).

func (*Ctx) RemoteIP

func (c *Ctx) RemoteIP() string

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) Set

func (c *Ctx) Set(key string, val any)

Set/Get share typed values across the chain (gin's c.Set/c.Get, string keys).

func (*Ctx) SetCookie

func (c *Ctx) SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)

func (*Ctx) SetRequestContext

func (c *Ctx) SetRequestContext(ctx context.Context)

SetRequestContext swaps the request's context (the auth/trace pattern of c.Request = c.Request.WithContext(ctx)).

func (*Ctx) SetSameSite

func (c *Ctx) SetSameSite(s http.SameSite)

SetSameSite + SetCookie mirror gin's cookie helpers used by auth/cookie.go.

func (*Ctx) ShouldBind

func (c *Ctx) ShouldBind(ptr any) error

ShouldBind fills fields tagged `form:"name"` from a parsed form body (url-encoded or multipart).

func (*Ctx) ShouldBindHeader

func (c *Ctx) ShouldBindHeader(ptr any) error

ShouldBindHeader fills fields tagged `header:"Name"` from request headers.

func (*Ctx) ShouldBindJSON

func (c *Ctx) ShouldBindJSON(ptr any) error

ShouldBindJSON decodes the request body as JSON into ptr.

func (*Ctx) ShouldBindQuery

func (c *Ctx) ShouldBindQuery(ptr any) error

ShouldBindQuery fills fields tagged `query:"name"` (or `form:"name"`) from the URL query.

func (*Ctx) ShouldBindUri

func (c *Ctx) ShouldBindUri(ptr any) error

ShouldBindUri fills fields tagged `uri:"name"` from path params.

func (*Ctx) Status

func (c *Ctx) Status(code int)

func (*Ctx) String

func (c *Ctx) String(status int, s 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).

func (*Ctx) Stringf

func (c *Ctx) Stringf(status int, format string, args ...any)

Stringf writes a printf-formatted text body, for the rare caller that needs formatting (kept separate from String so the common path stays vet-clean).

func (*Ctx) Written

func (c *Ctx) Written() bool

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.

func NewGroup

func NewGroup(r Router, prefix string, mw ...HandlerFunc) Group

NewGroup builds a Group over any Router. Adapters return this from Group().

type H

type H = map[string]any

H is the JSON map shorthand (drop-in for gin.H).

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) Write

func (w *ResponseWriter) Write(b []byte) (int, error)

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 RouteInfo

type RouteInfo struct {
	Method string
	Path   string
}

RouteInfo is one mounted route, for dashboard introspection (gin.RouteInfo).

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.

Jump to

Keyboard shortcuts

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