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 AppendFileJSON(dst []byte, f File) []byte
- func AssembleOpenAPI() (jsonDoc []byte, err error)
- 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) (*jsonbind.Object, 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 []byte) ([]bool, error)
- func DecodeJSONFloat64(raw json.RawMessage) (float64, error)
- func DecodeJSONFloat64Slice(raw []byte) ([]float64, error)
- func DecodeJSONInt(raw json.RawMessage) (int, error)
- func DecodeJSONInt64(raw json.RawMessage) (int64, error)
- func DecodeJSONInt64Slice(raw []byte) ([]int64, error)
- func DecodeJSONIntSlice(raw []byte) ([]int, error)
- func DecodeJSONMapStringString(raw []byte) (map[string]string, error)
- func DecodeJSONString(raw json.RawMessage) (string, error)
- func DecodeJSONStringSlice(raw []byte) ([]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 OpenAPIJSON(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 Queries(r *http.Request) url.Values
- func QueryLookup(q url.Values, key string) (string, bool)
- func QueryValue(r *http.Request, key string) (string, bool)
- func RawJSONArray(raw []byte) ([][]byte, error)
- func RawJSONMap(raw []byte) (*jsonbind.Object, error)
- func ReadBody(r *http.Request, wantForm, wantFiles bool) (*jsonbind.Object, map[string]string, map[string]File, error)
- func ReadJSONObject(r *http.Request) (*jsonbind.Object, error)
- func RegisterBind[T any](fn func(*http.Request) (T, error))
- func RegisterOpenAPIFragment(id string, jsonDoc []byte)
- func RegisterOpenAPIFragmentString(id string, jsonDoc string)
- func RegisterWrite[T any](fn func(http.ResponseWriter, *http.Request, T) error)
- func ResetOpenAPIFragments()
- 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 *jsonbind.Object, exclude []string) (map[string]any, error)
- func RestJSONNames(jsonBody *jsonbind.Object, exclude []string) []string
- func SetMaxJSONBodyBytes(n int64)
- func SetMaxMultipartBodyBytes(n int64)
- func SetOpenAPIInfo(info OpenAPIInfo) error
- func SetStreamErrorHandler(fn func(error))
- 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 WriteJSONBytes(w http.ResponseWriter, status int, data []byte) error
- func WriteStatus[T any](w http.ResponseWriter, r *http.Request, status int, value T) error
- func WriteStream[T any](w http.ResponseWriter, r *http.Request, fn func(*Stream[T]) error)
- type FieldError
- type File
- type HTTPError
- type OpenAPIInfo
- type Problem
- type Stream
- type StreamFormat
Constants ¶
const ( // StreamSSE is text/event-stream (data: <json>\n\n). StreamSSE = bindcore.StreamSSE // StreamNDJSON is application/x-ndjson (one JSON object per line). // Same family as JSONL / NDJSON; not a single JSON array document. StreamNDJSON = bindcore.StreamNDJSON // StreamJSONArray is application/json as one JSON array document: // [obj1,obj2,...] with items appended incrementally and closed by Close. StreamJSONArray = bindcore.StreamJSONArray )
const DefaultMaxJSONBodyBytes = jsonbind.DefaultMaxJSONBodyBytes
DefaultMaxJSONBodyBytes is the default cap for JSON document reads (1 MiB).
const DefaultMaxMultipartBodyBytes = bindcore.DefaultMaxMultipartBodyBytes
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 = bindcore.DefaultMultipartMaxMemory
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 AppendFileJSON ¶ added in v0.4.0
AppendFileJSON appends an uploaded file the way encoding/json rendered it before generated encoders stopped going through reflection: exported fields in declaration order, with the content base64-encoded.
func AssembleOpenAPI ¶ added in v0.1.11
AssembleOpenAPI merges every registered package fragment and returns a deterministic OpenAPI 3.1 JSON document.
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 ¶
BytesJSONMap splits a full JSON object document into its raw fields.
func CheckDateTime ¶
CheckDateTime reports whether s is RFC3339 (fractional seconds accepted).
func CheckEmail ¶
CheckEmail reports whether s is a pragmatic (non-RFC5322) email. Empty string returns false; callers skip empty optional fields before calling.
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 ¶
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 ¶
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 ¶
DecodeJSONInt64Slice decodes a JSON array of int64.
func DecodeJSONIntSlice ¶
DecodeJSONIntSlice decodes a JSON array of ints.
func DecodeJSONMapStringString ¶
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 ¶
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 OpenAPIJSON ¶
func OpenAPIJSON(w http.ResponseWriter, r *http.Request)
OpenAPIJSON serves the assembled OpenAPI document as application/json.
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 Queries ¶ added in v0.4.3
Queries parses the request's query string once. Generated binders call this a single time per request and resolve each field with QueryLookup, instead of re-parsing the raw query per field the way QueryValue does.
func QueryLookup ¶ added in v0.4.3
QueryLookup returns the first value for key from pre-parsed query values.
func QueryValue ¶
QueryValue returns the first query parameter value for key.
func RawJSONArray ¶
RawJSONArray splits a JSON array into its raw element values.
func RawJSONMap ¶
RawJSONMap splits a JSON object value into its raw fields.
func ReadBody ¶ added in v0.4.3
func ReadBody(r *http.Request, wantForm, wantFiles bool) (*jsonbind.Object, map[string]string, map[string]File, error)
ReadBody dispatches on the request content type and reads the body at most once on behalf of a generated binder. wantForm/wantFiles mirror which body kinds the binder's fields can consume; a request whose content type matches none of them yields all-nil results without error, and the binder then falls back to its per-field defaults.
func ReadJSONObject ¶ added in v0.4.0
ReadJSONObject splits a JSON object body into its raw fields.
Generated binders need random access by name, because a field may also come from the query string or a form and the tag decides which source wins. The returned Object holds subslices of the body, so this costs one pass and one slice rather than a map plus a copy of every member.
Non-object JSON (arrays, scalars, null) 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 RegisterOpenAPIFragment ¶ added in v0.1.11
RegisterOpenAPIFragment registers a generated package fragment. ID should be the package import path. Assembly reports conflicting repeated IDs.
func RegisterOpenAPIFragmentString ¶ added in v0.4.3
RegisterOpenAPIFragmentString is RegisterOpenAPIFragment for a string document. Generated code registers its embedded fragment constant through this so the constant is stored as-is, without a startup copy.
func RegisterWrite ¶
RegisterWrite registers a generated writer for T.
func ResetOpenAPIFragments ¶ added in v0.1.11
func ResetOpenAPIFragments()
ResetOpenAPIFragments clears registered fragments. It is intended for tests.
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 RestJSONNames ¶ added in v0.4.0
RestJSONNames lists leftover JSON object keys not in exclude, so generated code can fill a map[string]json.RawMessage without this package converting between map types.
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.
The value lives in bindcore, so a process setting it once configures every transport runtime rather than only the one it happened to call.
n > 0 → use n bytes n <= 0 → restore DefaultMaxMultipartBodyBytes (1 MiB)
func SetOpenAPIInfo ¶ added in v0.1.11
func SetOpenAPIInfo(info OpenAPIInfo) error
SetOpenAPIInfo sets application-level metadata for the assembled document. Repeating the same value is harmless; a different second value is an error.
func SetStreamErrorHandler ¶ added in v0.4.9
func SetStreamErrorHandler(fn func(error))
SetStreamErrorHandler installs the destination for stream failures that happen after the response status has been sent. Passing nil discards them, which is the default: a runtime that logged on its own would be writing to a destination the caller did not choose.
The handler is shared with the fasthttp runtime, so installing it once covers both.
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). The document itself is derived in bindcore, so the other transport runtime writes the same bytes for the same error rather than reimplementing the rule.
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 WriteJSONBytes ¶ added in v0.4.0
func WriteJSONBytes(w http.ResponseWriter, status int, data []byte) error
WriteJSONBytes writes an already-encoded document. Generated writers build the body into a pooled buffer and hand it over here, so the response path never reflects over the value and never allocates an intermediate map.
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.
func WriteStream ¶ added in v0.4.9
WriteStream opens a negotiated stream, runs fn against it, and closes it.
It returns nothing. fn runs after the handler has returned on the fasthttp runtime, where an error cannot travel back to handler code, so neither surface offers one and the same handler source works on both.
A failure to open — before any byte is committed — becomes an ordinary Problem response. Once the stream is open the status is already sent, so an error from fn reaches the handler installed with SetStreamErrorHandler instead. Close runs either way, which is what keeps a JSON array document terminated when fn fails halfway through it.
Types ¶
type FieldError ¶
type FieldError = bindcore.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.
It is an alias so a model struct declaring a File field compiles against either transport runtime without naming one of them.
type HTTPError ¶
HTTPError is an HTTP-mapped error with optional RFC 9457 details and cause.
func AsHTTPError ¶
AsHTTPError extracts *HTTPError from err if present.
type OpenAPIInfo ¶ added in v0.1.11
OpenAPIInfo is application-owned metadata for the assembled document.
type Stream ¶
Stream is a typed incremental response stream.
Handler usage:
httpbind.WriteStream(w, r, func(s *httpbind.Stream[ChatEvent]) error {
if err := s.Write(ChatEvent{Type: "delta", Delta: "hi"}); err != nil {
return err
}
return s.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 and status are sent when the stream opens. WriteStream closes the stream, which is what writes the trailing ']' of the JSON array framing.
The framing lives in one place shared with the fasthttp runtime, so the same events produce the same bytes on either transport.
Events are encoded through the jsonbind codec registry: T must have a generated encoder (or one registered manually via jsonbind.RegisterEncode).
func NewStream
deprecated
NewStream negotiates transport format from the request, writes response headers and 200 once, and returns a stream for incremental Write calls.
Deprecated: use WriteStream. A caller-held stream has no fasthttp transcription, and it makes the trailing ']' of the JSON array framing depend on the caller remembering to defer Close.
type StreamFormat ¶
type StreamFormat = bindcore.StreamFormat
StreamFormat is the negotiated on-the-wire format for Stream[T].
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.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cliparser parses argv into a map of stable config keys using precomputed flag definitions.
|
Package cliparser parses argv into a map of stable config keys using precomputed flag definitions. |
|
codegen
Package codegen emits Go source that constructs cliparser.Def slices for Bind-style fields.
|
Package codegen emits Go source that constructs cliparser.Def slices for Bind-style fields. |
|
cmd
|
|
|
tinybind-gen
command
|
|
|
Package configbind loads Bind-style config from defaults, TOML, env, and CLI into structs.
|
Package configbind loads Bind-style config from defaults, TOML, env, and CLI into structs. |
|
codegen
Package codegen emits reflection-free configbind apply, flag, and env key tables.
|
Package codegen emits reflection-free configbind apply, flag, and env key tables. |
|
Package configpath resolves one config file path for configbind.
|
Package configpath resolves one config file path for configbind. |
|
Package dynamobind provides typed, reflection-free DynamoDB item binding on top of github.com/shibukawa/tinygodriver/nosql/dynamodb.
|
Package dynamobind provides typed, reflection-free DynamoDB item binding on top of github.com/shibukawa/tinygodriver/nosql/dynamodb. |
|
examples
|
|
|
demo
command
|
|
|
Package fasthttpbind is the fasthttp half of the binding runtime.
|
Package fasthttpbind is the fasthttp half of the binding runtime. |
|
Package firestorebind provides typed, reflection-free entity binding for Firestore in Datastore mode, on top of github.com/shibukawa/tinygodriver/nosql/datastore.
|
Package firestorebind provides typed, reflection-free entity binding for Firestore in Datastore mode, on top of github.com/shibukawa/tinygodriver/nosql/datastore. |
|
Package htmlbind is the rendering runtime for generated HTML templates.
|
Package htmlbind is the rendering runtime for generated HTML templates. |
|
delta
Package delta compares two renders of one chain and expresses the difference as operations a browser applies, so a screen already showing the document reaches the server's fresh render without a full page load.
|
Package delta compares two renders of one chain and expresses the difference as operations a browser applies, so a screen already showing the document reaches the server's fresh render without a full page load. |
|
Package htmlupdate serves HTML templates that can update themselves in place.
|
Package htmlupdate serves HTML templates that can update themselves in place. |
|
internal
|
|
|
benchfixture
Package benchfixture backs the benchmark table in the project README.
|
Package benchfixture backs the benchmark table in the project README. |
|
bindcore
Package bindcore holds the declarations both transport runtimes need and neither should own: the error model, the uploaded-file value, and the check helpers.
|
Package bindcore holds the declarations both transport runtimes need and neither should own: the error model, the uploaded-file value, and the check helpers. |
|
contextscan
Package contextscan names the package-level functions in a directory whose first parameter is a context.Context.
|
Package contextscan names the package-level functions in a directory whose first parameter is a context.Context. |
|
dynamofixture
Package dynamofixture exercises the generated DynamoDB item codec against the dynamobind runtime and the driver's wire protocol.
|
Package dynamofixture exercises the generated DynamoDB item codec against the dynamobind runtime and the driver's wire protocol. |
|
firestorefixture
Package firestorefixture exercises the generated Firestore entity codec against the firestorebind runtime and the driver's wire protocol.
|
Package firestorefixture exercises the generated Firestore entity codec against the firestorebind runtime and the driver's wire protocol. |
|
gensource
Package gensource identifies the Go files a generation run wrote.
|
Package gensource identifies the Go files a generation run wrote. |
|
godoc
Package godoc extracts documentation text from Go doc comments so host-side analysis can carry it into generated artifacts such as OpenAPI descriptions.
|
Package godoc extracts documentation text from Go doc comments so host-side analysis can carry it into generated artifacts such as OpenAPI descriptions. |
|
pagesfixture/pages/archive
Package archive is the route that needs the request itself rather than the address it was sent to.
|
Package archive is the route that needs the request itself rather than the address it was sent to. |
|
Package jsonbind provides generated, reflection-free JSON document codecs.
|
Package jsonbind provides generated, reflection-free JSON document codecs. |
|
Package minitoml parses a restricted TOML subset into a flat intermediate key/value form.
|
Package minitoml parses a restricted TOML subset into a flat intermediate key/value form. |
|
codegen
Package codegen emits reflection-free apply functions from intermediate minitoml.Document keys.
|
Package codegen emits reflection-free apply functions from intermediate minitoml.Document keys. |
|
Package routetree discovers a filesystem route tree and derives the stdlib ServeMux patterns, ancestor layout chains, and Go package names for it.
|
Package routetree discovers a filesystem route tree and derives the stdlib ServeMux patterns, ancestor layout chains, and Go package names for it. |
|
Package sqlbind provides generated, reflection-free database/sql row mapping.
|
Package sqlbind provides generated, reflection-free database/sql row mapping. |
|
templates
|
|
|
dynamobind
Package dynamobind parses and prints typed DynamoDB access-pattern sources.
|
Package dynamobind parses and prints typed DynamoDB access-pattern sources. |
|
firestorebind
Package firestorebind parses and prints typed Firestore Datastore access-pattern sources.
|
Package firestorebind parses and prints typed Firestore Datastore access-pattern sources. |
|
htmlbind
Package htmlbind parses typed HTML template sources into an AST.
|
Package htmlbind parses typed HTML template sources into an AST. |
|
internal/rawparse
Package rawparse provides the lossless dummy format parser used to exercise the shared template parser without HTML or SQL knowledge.
|
Package rawparse provides the lossless dummy format parser used to exercise the shared template parser without HTML or SQL knowledge. |
|
sqlbind
Package sqlbind parses and compiles typed SQL template sources.
|
Package sqlbind parses and compiles typed SQL template sources. |
|
templatefmt
Package templatefmt formats tinybind template sources.
|
Package templatefmt formats tinybind template sources. |