Documentation
¶
Overview ¶
Package httpbind provides generated, reflection-free net/http request and response binding. Standalone JSON and SQL mapping live in the jsonbind and sqlbind packages so consumers do not compile unrelated platform dependencies.
Index ¶
- Constants
- func BadRequest(problem Problem, cause ...error) error
- func Bind[T any](r *http.Request) (T, error)
- func BindError(field, location, message string) error
- func BytesJSONMap(data []byte) (map[string]json.RawMessage, error)
- func CheckDate(s string) bool
- func CheckDateTime(s string) bool
- func CheckEmail(s string) bool
- func CheckTime(s string) bool
- func CheckUUID(s string) bool
- func Conflict(problem Problem, cause ...error) error
- func CookieValue(r *http.Request, name string) (string, bool)
- func DecodeJSONBool(raw json.RawMessage) (bool, error)
- func DecodeJSONBoolSlice(raw json.RawMessage) ([]bool, error)
- func DecodeJSONFloat64(raw json.RawMessage) (float64, error)
- func DecodeJSONFloat64Slice(raw json.RawMessage) ([]float64, error)
- func DecodeJSONInt(raw json.RawMessage) (int, error)
- func DecodeJSONInt64(raw json.RawMessage) (int64, error)
- func DecodeJSONInt64Slice(raw json.RawMessage) ([]int64, error)
- func DecodeJSONIntSlice(raw json.RawMessage) ([]int, error)
- func DecodeJSONMapStringString(raw json.RawMessage) (map[string]string, error)
- func DecodeJSONString(raw json.RawMessage) (string, error)
- func DecodeJSONStringSlice(raw json.RawMessage) ([]string, error)
- func Forbidden(problem Problem, cause ...error) error
- func HeaderValue(r *http.Request, key string) string
- func Internal(err error) error
- func IsFormRequest(r *http.Request) bool
- func IsJSONRequest(r *http.Request) bool
- func IsMultipartRequest(r *http.Request) bool
- func MaxJSONBodyBytes() int64
- func MaxMultipartBodyBytes() int64
- func NotFound(problem Problem, cause ...error) error
- func OpenAPIDocumentJSON() []byte
- func OpenAPIDocumentYAML() []byte
- func OpenAPIJSON(w http.ResponseWriter, r *http.Request)
- func OpenAPIYAML(w http.ResponseWriter, r *http.Request)
- func ParseBool(s string) (bool, error)
- func ParseFloat64(s string) (float64, error)
- func ParseFormMap(r *http.Request) (map[string]string, error)
- func ParseInt(s string) (int, error)
- func ParseInt64(s string) (int64, error)
- func ParseMultipartMap(r *http.Request) (form map[string]string, files map[string]File, err error)
- func PathValue(r *http.Request, key string) string
- func PayloadTooLarge(problem Problem, cause ...error) error
- func QueryValue(r *http.Request, key string) (string, bool)
- func RawJSONArray(raw json.RawMessage) ([]json.RawMessage, error)
- func RawJSONMap(raw json.RawMessage) (map[string]json.RawMessage, error)
- func ReadJSONMap(r *http.Request) (map[string]json.RawMessage, error)
- func RegisterBind[T any](fn func(*http.Request) (T, error))
- func RegisterOpenAPI(jsonDoc, yamlDoc []byte)
- func RegisterWrite[T any](fn func(http.ResponseWriter, *http.Request, T) error)
- func RestFormAny(formBody map[string]string, exclude []string) map[string]any
- func RestFormRaw(formBody map[string]string, exclude []string) map[string]json.RawMessage
- func RestJSONAny(jsonBody map[string]json.RawMessage, exclude []string) (map[string]any, error)
- func RestJSONRaw(jsonBody map[string]json.RawMessage, exclude []string) map[string]json.RawMessage
- func SetMaxJSONBodyBytes(n int64)
- func SetMaxMultipartBodyBytes(n int64)
- func SwaggerUI(specURL string) http.Handler
- func Unauthorized(problem Problem, cause ...error) error
- func Validation(fields ...FieldError) error
- func Write[T any](w http.ResponseWriter, r *http.Request, value T) error
- func WriteError(w http.ResponseWriter, r *http.Request, err error)
- func WriteJSON(w http.ResponseWriter, status int, v any) error
- func WriteStatus[T any](w http.ResponseWriter, r *http.Request, status int, value T) error
- type FieldError
- type File
- type HTTPError
- type Problem
- type Stream
- type StreamFormat
Constants ¶
const DefaultMaxJSONBodyBytes = jsonbind.DefaultMaxJSONBodyBytes
DefaultMaxJSONBodyBytes is the default cap for JSON document reads (1 MiB).
const DefaultMaxMultipartBodyBytes int64 = 1 << 20
DefaultMaxMultipartBodyBytes is the default cap on multipart request bodies enforced by ParseMultipartMap (1 MiB). Override with SetMaxMultipartBodyBytes. Without this, io.ReadAll / unrestricted ParseMultipartForm would accept arbitrarily large bodies inside tinybind-go alone.
const DefaultMultipartMaxMemory int64 = 32 << 20
DefaultMultipartMaxMemory is the maxMemory argument passed to http.Request.ParseMultipartForm (how much of the form stays in RAM before spilling file parts to temp files). This is not a body size cap; see DefaultMaxMultipartBodyBytes.
Variables ¶
This section is empty.
Functions ¶
func BadRequest ¶
BadRequest returns a 400 Bad Request error.
func Bind ¶
Bind maps an HTTP request into a typed request value. Dispatch uses a registry of generated binders; field mapping does not use reflect.
func BytesJSONMap ¶
func BytesJSONMap(data []byte) (map[string]json.RawMessage, error)
BytesJSONMap decodes a full JSON document (bytes) as an object map.
func CheckDateTime ¶
CheckDateTime reports whether s is RFC3339 (or RFC3339Nano on failure).
func CheckEmail ¶
CheckEmail reports whether s is a pragmatic (non-RFC5322) email. Empty string returns false; callers skip empty optional fields before calling.
func CheckUUID ¶
CheckUUID reports whether s is a UUID string (8-4-4-4-12 hex with dashes). Version/variant bits are not enforced.
func CookieValue ¶
CookieValue returns a cookie value if present.
func DecodeJSONBool ¶
func DecodeJSONBool(raw json.RawMessage) (bool, error)
DecodeJSONBool unmarshals a JSON raw value as bool.
func DecodeJSONBoolSlice ¶
func DecodeJSONBoolSlice(raw json.RawMessage) ([]bool, error)
DecodeJSONBoolSlice decodes a JSON array of bools.
func DecodeJSONFloat64 ¶
func DecodeJSONFloat64(raw json.RawMessage) (float64, error)
DecodeJSONFloat64 unmarshals a JSON raw value as float64.
func DecodeJSONFloat64Slice ¶
func DecodeJSONFloat64Slice(raw json.RawMessage) ([]float64, error)
DecodeJSONFloat64Slice decodes a JSON array of float64.
func DecodeJSONInt ¶
func DecodeJSONInt(raw json.RawMessage) (int, error)
DecodeJSONInt unmarshals a JSON raw value as int.
func DecodeJSONInt64 ¶
func DecodeJSONInt64(raw json.RawMessage) (int64, error)
DecodeJSONInt64 unmarshals a JSON raw value as int64.
func DecodeJSONInt64Slice ¶
func DecodeJSONInt64Slice(raw json.RawMessage) ([]int64, error)
DecodeJSONInt64Slice decodes a JSON array of int64.
func DecodeJSONIntSlice ¶
func DecodeJSONIntSlice(raw json.RawMessage) ([]int, error)
DecodeJSONIntSlice decodes a JSON array of ints.
func DecodeJSONMapStringString ¶
func DecodeJSONMapStringString(raw json.RawMessage) (map[string]string, error)
DecodeJSONMapStringString decodes a JSON object with string values.
func DecodeJSONString ¶
func DecodeJSONString(raw json.RawMessage) (string, error)
DecodeJSONString unmarshals a JSON raw value as string.
func DecodeJSONStringSlice ¶
func DecodeJSONStringSlice(raw json.RawMessage) ([]string, error)
DecodeJSONStringSlice decodes a JSON array of strings.
func HeaderValue ¶
HeaderValue returns a request header.
func IsFormRequest ¶
IsFormRequest reports application/x-www-form-urlencoded.
func IsJSONRequest ¶
IsJSONRequest reports whether the request body should be treated as JSON. Matches application/json, text/json, and *+json types such as application/problem+json (RFC 7807 / RFC 9457).
func IsMultipartRequest ¶
IsMultipartRequest reports multipart/form-data.
func MaxJSONBodyBytes ¶
func MaxJSONBodyBytes() int64
MaxJSONBodyBytes returns the effective JSON body limit.
func MaxMultipartBodyBytes ¶
func MaxMultipartBodyBytes() int64
MaxMultipartBodyBytes returns the effective global multipart body limit.
func OpenAPIDocumentJSON ¶
func OpenAPIDocumentJSON() []byte
OpenAPIDocumentJSON returns the registered OpenAPI JSON document (copy).
func OpenAPIDocumentYAML ¶
func OpenAPIDocumentYAML() []byte
OpenAPIDocumentYAML returns the registered OpenAPI YAML document (copy).
func OpenAPIJSON ¶
func OpenAPIJSON(w http.ResponseWriter, r *http.Request)
OpenAPIJSON serves the embedded OpenAPI document as application/json.
func OpenAPIYAML ¶
func OpenAPIYAML(w http.ResponseWriter, r *http.Request)
OpenAPIYAML serves the embedded OpenAPI document as application/yaml.
func ParseFloat64 ¶
ParseFloat64 converts a string to float64.
func ParseFormMap ¶
ParseFormMap parses urlencoded form body into a flat map (first value wins).
func ParseMultipartMap ¶
ParseMultipartMap parses a multipart/form-data body into scalar form fields (first value wins) and named file parts (first file wins per field name).
The request body is capped at MaxMultipartBodyBytes() so tinybind-go itself enforces a size limit (default 1 MiB): Content-Length is checked when known, r.Body is wrapped with http.MaxBytesReader, and per-file reads use LimitReader. Oversized bodies and oversize file parts map to HTTP 413.
func PayloadTooLarge ¶
PayloadTooLarge returns a 413 Payload Too Large error.
func QueryValue ¶
QueryValue returns the first query parameter value for key.
func RawJSONArray ¶
func RawJSONArray(raw json.RawMessage) ([]json.RawMessage, error)
RawJSONArray decodes a JSON array RawMessage into element raw values.
func RawJSONMap ¶
func RawJSONMap(raw json.RawMessage) (map[string]json.RawMessage, error)
RawJSONMap decodes a JSON object RawMessage into a map of raw fields.
func ReadJSONMap ¶
ReadJSONMap decodes a JSON object body into a map of raw messages. Used by generated binders so they can pick named fields without reflect on T. Non-object JSON (arrays, scalars) fails with 400 — required when payload:"*" rest maps are used.
func RegisterBind ¶
RegisterBind registers a generated binder for T. Call from generated init(); field mapping lives entirely inside fn.
func RegisterOpenAPI ¶
func RegisterOpenAPI(jsonDoc, yamlDoc []byte)
RegisterOpenAPI stores generated OpenAPI document bytes for OpenAPIJSON/OpenAPIYAML. Called from generated init(); not a handwritten OpenAPI source of truth.
func RegisterWrite ¶
RegisterWrite registers a generated writer for T.
func RestFormAny ¶
RestFormAny builds map[string]any from leftover form keys not in exclude (string values).
func RestFormRaw ¶
RestFormRaw builds map[string]json.RawMessage from leftover form keys (JSON-encoded strings).
func RestJSONAny ¶
RestJSONAny builds map[string]any from leftover JSON object keys not in exclude. Nested JSON values are decoded into any (objects/arrays/numbers/bools/strings/null). Prefer non-nil empty map when nothing remains.
func RestJSONRaw ¶
func RestJSONRaw(jsonBody map[string]json.RawMessage, exclude []string) map[string]json.RawMessage
RestJSONRaw builds map[string]json.RawMessage from leftover JSON object keys not in exclude.
func SetMaxJSONBodyBytes ¶
func SetMaxJSONBodyBytes(n int64)
SetMaxJSONBodyBytes changes the process-wide JSON body limit. A non-positive value restores DefaultMaxJSONBodyBytes.
func SetMaxMultipartBodyBytes ¶
func SetMaxMultipartBodyBytes(n int64)
SetMaxMultipartBodyBytes sets the global multipart body size limit used by ParseMultipartMap (and generated binders). The limit wraps r.Body with http.MaxBytesReader and bounds per-file reads.
n > 0 → use n bytes n <= 0 → restore DefaultMaxMultipartBodyBytes (1 MiB)
func SwaggerUI ¶
SwaggerUI returns an http.Handler that serves a minimal Swagger UI page loading the OpenAPI document from specURL (e.g. "/openapi.json").
Assets are loaded from a public CDN; this handler does not embed Swagger UI binaries. Mount freely, e.g.:
mux.Handle("GET /docs/{$}", httpbind.SwaggerUI("/openapi.json"))
func Unauthorized ¶
Unauthorized returns a 401 Unauthorized error.
func Validation ¶
func Validation(fields ...FieldError) error
Validation returns a 400 Bad Request validation error with field details.
func Write ¶
Write serializes a typed response value to the HTTP response via a registered writer. Status is always 200 OK; use WriteStatus for other success codes.
func WriteError ¶
func WriteError(w http.ResponseWriter, r *http.Request, err error)
WriteError writes err as an RFC 9457 Problem Details response. Internal causes are not exposed in the client body.
JSON is written without encoding/json for the problem document so TinyGo does not hit unimplemented reflect.AssignableTo when binders also use json.RawMessage (a known interaction in TinyGo's encoding/json).
func WriteJSON ¶
func WriteJSON(w http.ResponseWriter, status int, v any) error
WriteJSON is a helper for generated writers: encode a pre-built map/slice without reflecting over application structs. Content-Type is application/json.
func WriteStatus ¶
WriteStatus serializes value with an explicit HTTP status code using the registered encoder for T (no field-walking reflection on T). For status 204 No Content, the body is not written.
Types ¶
type FieldError ¶
FieldError describes a single field-level validation failure.
func Field ¶
func Field(field, location, message string) FieldError
Field builds a field-level validation error.
type File ¶
File is an uploaded file bound from a multipart/form-data part. After a successful bind, Filename, ContentType (when the client sent one), Size, and Content are populated from the named file part.
type HTTPError ¶
type HTTPError struct {
Status int
Title string
Problem Problem
Fields []FieldError
// contains filtered or unexported fields
}
HTTPError is an HTTP-mapped error with optional RFC 9457 details and cause.
func AsHTTPError ¶
AsHTTPError extracts *HTTPError from err if present. Implemented without errors.As so TinyGo does not require reflect.AssignableTo (unimplemented for interfaces in TinyGo 0.40), which otherwise panics when Bind's json.RawMessage path is also linked into the same binary.
type Stream ¶
type Stream[T any] struct { // contains filtered or unexported fields }
Stream is a typed incremental response stream.
Ideal handler usage:
stream, err := httpbind.NewStream[ChatEvent](w, r)
if err != nil { ... }
defer stream.Close()
_ = stream.Write(ChatEvent{Type: "delta", Delta: "hi"})
_ = stream.Write(ChatEvent{Type: "done"})
Format (SSE vs NDJSON vs JSON array) is chosen once by rule:stream-content-negotiation. Write may be called many times; headers/status are sent only in NewStream. JSON array framing requires Close (via defer) so the trailing ']' is written.
func NewStream ¶
NewStream negotiates transport format from the request, writes response headers and 200 once, and returns a stream for incremental Write calls.
func (*Stream[T]) Close ¶
Close marks the stream finished. Idempotent. For JSON array format, Close writes the trailing ']' (or "[]" if no Write). SSE and NDJSON do not require a special trailer; still call Close for symmetry.
func (*Stream[T]) Format ¶
func (s *Stream[T]) Format() StreamFormat
Format returns the negotiated stream format (sse | ndjson | json-array).
type StreamFormat ¶
type StreamFormat string
StreamFormat is the negotiated on-the-wire format for Stream[T].
const ( // StreamSSE is text/event-stream (data: <json>\n\n). StreamSSE StreamFormat = "sse" // StreamNDJSON is application/x-ndjson (one JSON object per line). // Same family as JSONL / NDJSON; not a single JSON array document. StreamNDJSON StreamFormat = "ndjson" // StreamJSONArray is application/json as one JSON array document: // [obj1,obj2,...] with items appended incrementally and closed by Close. StreamJSONArray StreamFormat = "json-array" )
func NegotiateStreamFormat ¶
func NegotiateStreamFormat(r *http.Request) StreamFormat
NegotiateStreamFormat selects SSE, NDJSON, or JSON array using:
- ?stream= query
- Accept
- User-Agent heuristics
- default NDJSON
Exported for tests and advanced callers.
Note: NDJSON/JSONL (line-delimited objects) is distinct from JSON array (a single [...] document). application/json selects the array form; application/x-ndjson / application/jsonl select NDJSON.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
cmd
|
|
|
tinybind-gen
command
|
|
|
examples
|
|
|
demo
command
|
|
|
internal
|
|
|
Package jsonbind provides generated, reflection-free JSON document codecs.
|
Package jsonbind provides generated, reflection-free JSON document codecs. |
|
Package sqlbind provides generated, reflection-free database/sql row mapping.
|
Package sqlbind provides generated, reflection-free database/sql row mapping. |