Documentation
¶
Overview ¶
Package server provides typed HTTP handlers, OpenAPI generation, and a bring-your-own-router adapter model. An API owns request binding, validation, response serialization, middleware, and the OpenAPI document, and delegates path matching to a pluggable Adapter — the standard-library ServeMuxAdapter by default, or any router you wrap. Route patterns support params (:id) and a trailing wildcard (*path).
Beyond routing it provides:
- Middleware at root, group, and route scope (see Middleware, APIGroup.Use, WithMiddleware, Chain, and MiddlewareFromFunc).
- Typed route registration with OpenAPI output (Register) and typed Server-Sent Events streaming (RegisterStream, EventStream, Stream).
- Pluggable error handling (ErrorHandler, DefaultErrorHandler) and custom not-found / method-not-allowed handlers.
- Per-route request body limits (WithMaxBodyBytes) and mounting of arbitrary http.Handlers (Mount).
- Pluggable typed-route codecs (APIConfig.Codecs) with per-route request and response restrictions (WithRequestContentTypes, WithResponseContentTypes).
- OpenAPI security schemes (AddSecurityScheme, BearerScheme, APIKeyScheme, BasicScheme) and per-operation security requirements (Operation.Security).
- Typed request-scoped context keys (NewContextKey) and the matched route template (RoutePattern) for logging and metrics.
Index ¶
- Constants
- Variables
- func AcquireGeneratedJSONBuffer() *[]byte
- func DecodeRequestJSONBodyFast(req *http.Request, dst any) error
- func DecodeRequestJSONBodyStrictFast(req *http.Request, dst any, bodyRequired bool, required []RequiredJSONField) error
- func DefaultErrorHandler(w http.ResponseWriter, _ *http.Request, err error)
- func DeleteCookie(w http.ResponseWriter, name string)
- func EnsureMultipartForm(req *http.Request) error
- func EnsureSingleJSONValue(decoder *json.Decoder) error
- func GeneratedTypeKey(t reflect.Type) string
- func GetCookie(r *http.Request, name string) (string, error)
- func GetCookieOr(r *http.Request, name, defaultValue string) string
- func HasPathTraversal(path string) bool
- func JoinValidationPointer(base string, parts ...string) string
- func NegotiateResponseContentType(req *http.Request, mediaTypes ...string) error
- func Param(req *http.Request, name string) string
- func ParseRequest[I any](req *http.Request) (*I, error)
- func ParseRequestWithCodecs[I any](req *http.Request, codecs []Codec) (*I, error)
- func ReadMultipartFiles(req *http.Request, name string) ([]*multipart.FileHeader, bool, error)
- func ReadMultipartFormValues(req *http.Request, name string) ([]string, bool, error)
- func ReadRequestJSONBody(req *http.Request) ([]byte, error)
- func ReadRequestJSONBodyFast(req *http.Request) ([]byte, error)
- func Register[I, O any](grp RouteTarget, op Operation, handler TypedHandler[I, O], opts ...RouteOption)
- func RegisterE[I, O any](grp RouteTarget, op Operation, handler TypedHandler[I, O], opts ...RouteOption) error
- func RegisterGeneratedCodec(meta GeneratedRouteMeta, codec GeneratedRouteCodec)
- func RegisterGeneratedManifest(routes ...GeneratedRouteMeta)
- func RegisterStream[I, O any](grp RouteTarget, op Operation, handler StreamHandler[I, O], ...)
- func RegisterStreamE[I, O any](grp RouteTarget, op Operation, handler StreamHandler[I, O], ...) error
- func ReleaseGeneratedJSONBuffer(buf *[]byte)
- func RoutePattern(req *http.Request) string
- func SchemaComponentName(t reflect.Type) string
- func ServerPathToOpenAPIPath(path string) string
- func SetCookie(w http.ResponseWriter, cfg CookieConfig)
- func SetCookieDefault(w http.ResponseWriter, name, value string)
- func SplitRouteFast(route string) []string
- func UseJSONCodecForRequest(req *http.Request, codecs []Codec) (bool, error)
- func UseJSONCodecForResponse(req *http.Request, codecs []Codec) (bool, error)
- func ValidateJSONContentType(contentType string) error
- func ValidateRequiredJSONFields(body []byte, required []RequiredJSONField) error
- func ValidateUUID(value string) bool
- func ValidationStringLength(value string) int
- func Wildcard(req *http.Request) string
- func WriteJSON(w http.ResponseWriter, status int, v any) error
- func WriteSuccess(w http.ResponseWriter, status int, data any) error
- func WriteSuccessWithCodecs(w http.ResponseWriter, req *http.Request, status int, data any, codecs []Codec) error
- func WriteTypedResponse[O any](w http.ResponseWriter, out *O) error
- type API
- func (a *API) AddSecurityScheme(name string, scheme *SecurityScheme)
- func (a *API) Codecs() []Codec
- func (a *API) DELETE(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) GET(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) Group(prefix string, mw ...Middleware) *APIGroup
- func (a *API) HEAD(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) Handle(method, pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) HandleE(method, pattern string, fn HandlerFunc, opts ...RouteOption) error
- func (a *API) Mount(prefix string, handler http.Handler) error
- func (a *API) MountFunc(prefix string, handler http.HandlerFunc) error
- func (a *API) MountOpenAPI(path string) error
- func (a *API) OPTIONS(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) OpenAPI() *openapi.OpenAPI
- func (a *API) OpenAPIHandler() HandlerFunc
- func (a *API) PATCH(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) POST(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) PUT(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (a *API) RegisteredOperations() []RegisteredOperation
- func (a *API) SchemaRegistry() *openapi.Registry
- func (a *API) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (a *API) SetErrorHandler(h ErrorHandler)
- func (a *API) SetMethodNotAllowedHandler(h http.Handler)
- func (a *API) SetNotFoundHandler(h http.Handler)
- func (a *API) Use(mw ...Middleware)
- func (a *API) UseHTTP(mw ...ServeHTTPMiddleware)
- func (a *API) UseNamed(mws ...NamedMiddleware)
- func (a *API) UseServeHTTP(mw ServeHTTPMiddleware)
- type APIConfig
- type APIGroup
- func (g *APIGroup) DELETE(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) GET(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) Group(prefix string, mw ...Middleware) *APIGroup
- func (g *APIGroup) HEAD(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) Handle(method, pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) HandleE(method, pattern string, fn HandlerFunc, opts ...RouteOption) error
- func (g *APIGroup) OPTIONS(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) PATCH(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) POST(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) PUT(pattern string, fn HandlerFunc, opts ...RouteOption)
- func (g *APIGroup) Use(mw ...Middleware) *APIGroup
- func (g *APIGroup) UseNamed(mws ...NamedMiddleware) *APIGroup
- type Adapter
- type Codec
- type Config
- type ContextKey
- type CookieConfig
- type DataResponse
- type ErrorHandler
- type EventStream
- type GeneratedRouteCodec
- type GeneratedRouteMeta
- type HTTPError
- type HandlerFunc
- type JSONCodec
- func (JSONCodec) AcquireGeneratedSuccessBuffer() *[]byte
- func (JSONCodec) AppendBool(dst []byte, v bool) []byte
- func (JSONCodec) AppendFloat(dst []byte, v float64) []byte
- func (JSONCodec) AppendInt(dst []byte, v int64) []byte
- func (JSONCodec) AppendString(dst []byte, v string) []byte
- func (JSONCodec) AppendUint(dst []byte, v uint64) []byte
- func (JSONCodec) DecodeRequest(req *http.Request, dst any) error
- func (JSONCodec) DecodeRequestStrict(req *http.Request, dst any, bodyRequired bool, required []RequiredJSONField) error
- func (JSONCodec) EncodeSuccess(w http.ResponseWriter, status int, data any) error
- func (JSONCodec) MediaType() string
- func (JSONCodec) ReadRequest(req *http.Request) ([]byte, error)
- func (JSONCodec) ReleaseGeneratedSuccessBuffer(buf *[]byte)
- func (JSONCodec) WriteGeneratedSuccess(w http.ResponseWriter, status int, body []byte) error
- type Middleware
- type MiddlewareFunc
- type NamedMiddleware
- type OpenAPIInfo
- type Operation
- type RegisteredOperation
- type RequiredJSONField
- type RouteOption
- type RouteTarget
- type SSEEvent
- type SecurityRequirement
- type SecurityScheme
- type ServeHTTPMiddleware
- type ServeMuxAdapter
- type Server
- type Stream
- type StreamHandler
- type TypedHandler
- type ValidationError
- type ValidationProblem
- type ValidationSubject
Constants ¶
const ( ValidationSubjectString = validation.SubjectString ValidationSubjectNumber = validation.SubjectNumber ValidationSubjectCollection = validation.SubjectCollection )
const ( ValidationRuleMin = validation.RuleMin ValidationRuleMax = validation.RuleMax ValidationRuleLen = validation.RuleLen ValidationRuleMinItems = validation.RuleMinItems ValidationRuleMaxItems = validation.RuleMaxItems ValidationRuleOneOf = validation.RuleOneOf ValidationRulePattern = validation.RulePattern ValidationRuleEmail = validation.RuleEmail ValidationRuleURL = validation.RuleURL ValidationRuleUUID = validation.RuleUUID )
Variables ¶
var ErrStreamClosed = errors.New("server: event stream is closed")
ErrStreamClosed is returned by EventStream methods after the stream has been closed.
Functions ¶
func AcquireGeneratedJSONBuffer ¶
func AcquireGeneratedJSONBuffer() *[]byte
func DefaultErrorHandler ¶
func DefaultErrorHandler(w http.ResponseWriter, _ *http.Request, err error)
DefaultErrorHandler is the ErrorHandler used when an API is not given a custom one. It maps HTTPError and validation errors to RFC 9457 problem+json responses, treats unknown errors as 500, and never overwrites a response that a handler already started writing.
func DeleteCookie ¶
func DeleteCookie(w http.ResponseWriter, name string)
func EnsureMultipartForm ¶
EnsureMultipartForm parses req as multipart/form-data if it has not already been parsed. It is used by reflection and generated request binders.
func EnsureSingleJSONValue ¶
func GeneratedTypeKey ¶
func HasPathTraversal ¶
func JoinValidationPointer ¶
func NegotiateResponseContentType ¶
NegotiateResponseContentType returns 406 when req's Accept header does not allow any of the response media types. An absent Accept header accepts any response. Passing no media types is treated as a response with no negotiated body.
func ParseRequestWithCodecs ¶
func ReadMultipartFiles ¶
ReadMultipartFiles reads all uploaded files for a multipart file field.
func ReadMultipartFormValues ¶
ReadMultipartFormValues reads all values for a multipart form field.
func Register ¶
func Register[I, O any](grp RouteTarget, op Operation, handler TypedHandler[I, O], opts ...RouteOption)
func RegisterE ¶
func RegisterE[I, O any](grp RouteTarget, op Operation, handler TypedHandler[I, O], opts ...RouteOption) error
func RegisterGeneratedCodec ¶
func RegisterGeneratedCodec(meta GeneratedRouteMeta, codec GeneratedRouteCodec)
func RegisterGeneratedManifest ¶
func RegisterGeneratedManifest(routes ...GeneratedRouteMeta)
func RegisterStream ¶
func RegisterStream[I, O any](grp RouteTarget, op Operation, handler StreamHandler[I, O], opts ...RouteOption)
RegisterStream registers a typed Server-Sent Events endpoint. It panics on invalid setup; use RegisterStreamE for the error-returning form.
func RegisterStreamE ¶
func RegisterStreamE[I, O any](grp RouteTarget, op Operation, handler StreamHandler[I, O], opts ...RouteOption) error
RegisterStreamE registers a typed Server-Sent Events endpoint. Unlike RegisterE (which requires a generated codec), streaming endpoints bind their input via reflection (ParseRequest) — there is no generated codec for a streamed response — and therefore always validate the input at runtime. Operation.SkipValidateRequest only suppresses the registration-time validation-rule check, not runtime input validation. The response is documented in OpenAPI as a text/event-stream whose data frames match type O.
Root-, group-, and route-level middleware (via opts) all apply.
func ReleaseGeneratedJSONBuffer ¶
func ReleaseGeneratedJSONBuffer(buf *[]byte)
func RoutePattern ¶
RoutePattern returns the route template that matched the request (for example "/users/:id"), or "" if no tyche route matched. It is suitable as a low-cardinality label for logs and metrics, unlike the concrete request path.
func SchemaComponentName ¶
func ServerPathToOpenAPIPath ¶
func SetCookie ¶
func SetCookie(w http.ResponseWriter, cfg CookieConfig)
func SetCookieDefault ¶
func SetCookieDefault(w http.ResponseWriter, name, value string)
func SplitRouteFast ¶
SplitRouteFast splits a route into its "/"-separated segments without allocating substrings for the separators. It panics on a route that does not start with "/". A bare "/" yields no segments.
func UseJSONCodecForRequest ¶
func UseJSONCodecForResponse ¶
func ValidateJSONContentType ¶
func ValidateRequiredJSONFields ¶
func ValidateRequiredJSONFields(body []byte, required []RequiredJSONField) error
func ValidateUUID ¶
func ValidationStringLength ¶
func WriteSuccess ¶
func WriteSuccess(w http.ResponseWriter, status int, data any) error
WriteSuccess writes a successful JSON response wrapped in the standard DataResponse envelope.
func WriteSuccessWithCodecs ¶
func WriteTypedResponse ¶
func WriteTypedResponse[O any](w http.ResponseWriter, out *O) error
Types ¶
type API ¶
type API struct {
// contains filtered or unexported fields
}
API is a router-agnostic tyche server. It owns the OpenAPI document, schema registry, error handling, and middleware composition, and delegates all path matching to an Adapter. It implements RouteTarget, so Register / RegisterStream can register directly on it (at the root prefix) or on any APIGroup it produces.
func NewAPI ¶
NewAPI builds an API over the given adapter. Config is optional; the zero value yields defaults (title "API", version "1.0.0", 10 MiB body limit).
api := server.NewAPI(server.NewServeMuxAdapter()) // defaults
api := server.NewAPI(server.NewServeMuxAdapter(), server.APIConfig{ ... })
func (*API) AddSecurityScheme ¶
func (a *API) AddSecurityScheme(name string, scheme *SecurityScheme)
AddSecurityScheme registers a named security scheme in the OpenAPI document.
func (*API) Codecs ¶
Codecs returns the server-wide codecs configured on the API. JSONCodec is present by default.
func (*API) DELETE ¶
func (a *API) DELETE(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) GET ¶
func (a *API) GET(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) Group ¶
func (a *API) Group(prefix string, mw ...Middleware) *APIGroup
Group returns a prefixed, optionally middleware-scoped registration target.
func (*API) HEAD ¶
func (a *API) HEAD(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) Handle ¶
func (a *API) Handle(method, pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) HandleE ¶
func (a *API) HandleE(method, pattern string, fn HandlerFunc, opts ...RouteOption) error
func (*API) Mount ¶
Mount attaches an arbitrary http.Handler at prefix, serving it for the prefix and every sub-path beneath it. The handler receives the unmodified request path. Routes registered via Mount are not included in the OpenAPI document.
func (*API) MountFunc ¶
func (a *API) MountFunc(prefix string, handler http.HandlerFunc) error
MountFunc is the http.HandlerFunc form of Mount.
func (*API) MountOpenAPI ¶
MountOpenAPI registers the OpenAPI JSON handler at path (GET + HEAD).
func (*API) OPTIONS ¶
func (a *API) OPTIONS(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) OpenAPIHandler ¶
func (a *API) OpenAPIHandler() HandlerFunc
OpenAPIHandler serves the document as JSON (cached after first render).
func (*API) PATCH ¶
func (a *API) PATCH(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) POST ¶
func (a *API) POST(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) PUT ¶
func (a *API) PUT(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*API) RegisteredOperations ¶
func (a *API) RegisteredOperations() []RegisteredOperation
RegisteredOperations returns a copy of the operations registered so far.
func (*API) SchemaRegistry ¶
SchemaRegistry returns the OpenAPI schema registry.
func (*API) ServeHTTP ¶
func (a *API) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP wraps the request in a tracked response writer (for "already written" detection) and hands it to the UseHTTP middleware chain, which wraps the router dispatch. Per-route body limits, middleware, and error rendering are applied by the handler the API registered with the adapter.
func (*API) SetErrorHandler ¶
func (a *API) SetErrorHandler(h ErrorHandler)
SetErrorHandler overrides the handler invoked when a route returns an error. Passing nil resets it to DefaultErrorHandler.
func (*API) SetMethodNotAllowedHandler ¶
SetMethodNotAllowedHandler overrides the handler used when a route exists for the path but not the request method. Passing nil resets the default.
func (*API) SetNotFoundHandler ¶
SetNotFoundHandler overrides the handler used when no route matches. Passing nil resets it to the default problem+json responder.
func (*API) Use ¶
func (a *API) Use(mw ...Middleware)
Use appends root-level middleware applied to every route and rebuilds the affected handler chains. Call during setup, before serving.
func (*API) UseHTTP ¶
func (a *API) UseHTTP(mw ...ServeHTTPMiddleware)
UseHTTP appends ServeHTTPMiddleware that wraps the entire router at the network edge, before routing — so it observes 404/405 responses and the final status. Call during setup, before serving.
func (*API) UseNamed ¶
func (a *API) UseNamed(mws ...NamedMiddleware)
UseNamed registers the Middleware of each NamedMiddleware at the root, preserving order.
func (*API) UseServeHTTP ¶
func (a *API) UseServeHTTP(mw ServeHTTPMiddleware)
UseServeHTTP is an alias for UseHTTP accepting a single middleware.
type APIConfig ¶
type APIConfig struct {
ErrorHandler ErrorHandler
OpenAPI OpenAPIInfo
Codecs []Codec
MaxRequestBodyBytes int64
}
APIConfig configures an API. The zero value is valid; NewAPI fills in sensible defaults (title "API", version "1.0.0", 10 MiB body limit).
type APIGroup ¶
type APIGroup struct {
// contains filtered or unexported fields
}
APIGroup is a prefixed, middleware-scoped registration target backed by an API and its Adapter.
func (*APIGroup) DELETE ¶
func (g *APIGroup) DELETE(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) GET ¶
func (g *APIGroup) GET(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) HEAD ¶
func (g *APIGroup) HEAD(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) Handle ¶
func (g *APIGroup) Handle(method, pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) HandleE ¶
func (g *APIGroup) HandleE(method, pattern string, fn HandlerFunc, opts ...RouteOption) error
func (*APIGroup) OPTIONS ¶
func (g *APIGroup) OPTIONS(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) PATCH ¶
func (g *APIGroup) PATCH(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) POST ¶
func (g *APIGroup) POST(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) PUT ¶
func (g *APIGroup) PUT(pattern string, fn HandlerFunc, opts ...RouteOption)
func (*APIGroup) Use ¶
func (g *APIGroup) Use(mw ...Middleware) *APIGroup
func (*APIGroup) UseNamed ¶
func (g *APIGroup) UseNamed(mws ...NamedMiddleware) *APIGroup
UseNamed registers the Middleware of each NamedMiddleware on the group, preserving order. It returns the group for chaining.
type Adapter ¶
type Adapter interface {
// Handle registers h to serve method+path.
Handle(method, path string, h http.Handler)
// ServeHTTP dispatches a request to the matching handler, falling back to
// the handlers set via SetFallback when nothing matches.
ServeHTTP(w http.ResponseWriter, r *http.Request)
// SetFallback installs the handler for unmatched paths (notFound) and for a
// path that matches a route registered under a different method
// (methodNotAllowed). Adapters that cannot distinguish the two may route
// both to notFound.
SetFallback(notFound, methodNotAllowed http.Handler)
}
Adapter is the bring-your-own-router seam.
An adapter owns exactly one thing: path matching. It maps a (method, path) pair to a handler and dispatches incoming requests to the right one, including 404/405 behaviour. Everything tyche is actually good at — generated codecs, validation, the {"data":…} envelope, problem+json errors, middleware composition, and OpenAPI generation — is layered on top by API and is independent of which adapter is used.
Paths are handed to Handle in tyche's native template form (":name" for a path parameter, "*name" for a trailing wildcard). Each adapter translates that to its router's own syntax. Adapters MUST ensure matched path parameters are readable through Param (i.e. via (*http.Request).PathValue) so the existing codec and reflection binders work unchanged.
type Codec ¶
type Codec interface {
MediaType() string
DecodeRequest(*http.Request, any) error
EncodeSuccess(http.ResponseWriter, int, any) error
}
Codec decodes request bodies and writes successful typed responses for one media type. JSONCodec is registered implicitly as the default codec.
type Config ¶
type Config struct {
Address string
ReadTimeout time.Duration
WriteTimeout time.Duration
IdleTimeout time.Duration
ShutdownTimeout time.Duration
MaxHeaderBytes int
}
func DefaultConfig ¶
type ContextKey ¶
type ContextKey[T any] struct { // contains filtered or unexported fields }
ContextKey is a typed key for storing and retrieving a value of type T on a context.Context. It removes the boilerplate of declaring an unexported key type plus paired getter/setter helpers for request-scoped metadata such as auth claims, trace identifiers, or tenant information:
var authKey = server.NewContextKey[Claims]("auth")
// in middleware
r = authKey.WithRequest(r, claims)
// in a handler
claims, ok := authKey.From(r.Context())
Each call to NewContextKey produces a distinct key, so values stored under different keys never collide even when T is identical.
func NewContextKey ¶
func NewContextKey[T any](name string) ContextKey[T]
NewContextKey returns a new, unique ContextKey for values of type T. The name is used only for debugging via the key's String method and need not be unique.
func (ContextKey[T]) From ¶
func (key ContextKey[T]) From(ctx context.Context) (T, bool)
From returns the value associated with this key on ctx and reports whether a value of type T was present.
func (ContextKey[T]) WithRequest ¶
func (key ContextKey[T]) WithRequest(r *http.Request, value T) *http.Request
WithRequest returns a shallow copy of r whose context carries value associated with this key. It is the request-oriented counterpart to ContextKey.WithValue.
type CookieConfig ¶
type DataResponse ¶
type DataResponse struct {
Data any `json:"data"`
}
DataResponse is the standard envelope for all successful API responses.
type ErrorHandler ¶
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error)
ErrorHandler converts an error returned by a HandlerFunc (or produced by the API, e.g. path traversal) into an HTTP response. Implementations should respect any response already written; see DefaultErrorHandler.
type EventStream ¶
type EventStream struct {
// contains filtered or unexported fields
}
EventStream writes a Server-Sent Events (text/event-stream) response. Obtain one with NewEventStream inside a regular HandlerFunc, or use RegisterStream for a typed, OpenAPI-documented streaming endpoint.
An EventStream is not safe for concurrent use by multiple goroutines; send from a single goroutine, or guard sends with your own synchronization.
func NewEventStream ¶
func NewEventStream(w http.ResponseWriter, r *http.Request) (*EventStream, error)
NewEventStream upgrades the response to a Server-Sent Events stream. It sets the appropriate headers (Content-Type: text/event-stream, no caching, and a hint to disable proxy buffering), writes a 200 status, and flushes so the client sees the response head immediately.
It returns an error only if the response writer does not support flushing, in which case no bytes are written and the caller may still produce a normal error response.
func (*EventStream) Comment ¶
func (s *EventStream) Comment(text string) error
Comment writes an SSE comment line (": text"). Comments are ignored by clients and are commonly used as keep-alive pings to keep idle connections open through proxies.
func (*EventStream) Context ¶
func (s *EventStream) Context() context.Context
Context returns the request context associated with the stream. Callers should stop sending when it is done (the client disconnected or a deadline elapsed).
func (*EventStream) Flush ¶
func (s *EventStream) Flush()
Flush forces any buffered data out to the client. Send and Comment already flush; Flush is exposed for callers writing through other means.
func (*EventStream) Send ¶
func (s *EventStream) Send(event SSEEvent) error
Send writes a single event frame and flushes it to the client. A write error (typically a disconnected client) marks the stream closed and is returned so the caller can stop.
func (*EventStream) SendData ¶
func (s *EventStream) SendData(v any) error
SendData sends an event whose only field is the JSON-encoded payload. It is shorthand for Send(SSEEvent{Data: v}).
type GeneratedRouteCodec ¶
type GeneratedRouteMeta ¶
type GeneratedRouteMeta struct {
PackagePath string
OperationID string
Method string
Path string
InputType string
OutputType string
InputTypeKey string
OutputTypeKey string
ResponseContentTypes []string
HasGeneratedCodec bool
}
func GeneratedRouteManifest ¶
func GeneratedRouteManifest() []GeneratedRouteMeta
type HandlerFunc ¶
type HandlerFunc func(http.ResponseWriter, *http.Request) error
func (HandlerFunc) ServeHTTP ¶
func (f HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)
type JSONCodec ¶
type JSONCodec struct{}
JSONCodec is the default application/json codec used by typed routes.
func (JSONCodec) AcquireGeneratedSuccessBuffer ¶
AcquireGeneratedSuccessBuffer returns a scratch buffer for generated JSON success response writers. Release it with ReleaseGeneratedSuccessBuffer.
func (JSONCodec) DecodeRequestStrict ¶
func (JSONCodec) EncodeSuccess ¶
func (JSONCodec) ReleaseGeneratedSuccessBuffer ¶
func (JSONCodec) WriteGeneratedSuccess ¶
type Middleware ¶
type Middleware func(next HandlerFunc) HandlerFunc
func Chain ¶
func Chain(mw ...Middleware) Middleware
Chain composes multiple middleware into a single Middleware. The first middleware in the list runs outermost (closest to the network) and the last runs innermost (closest to the handler), matching the order they would run if applied individually via [Group.Use]. It is handy for packaging a named group of middleware for reuse:
api.Use(server.Chain( middleware.RequestID(), middleware.Auth(authSvc), middleware.AccessLog(logger), ))
func MiddlewareFromFunc ¶
func MiddlewareFromFunc(fn MiddlewareFunc) Middleware
MiddlewareFromFunc adapts a MiddlewareFunc into a Middleware. It lets middleware authors write a single function body instead of nesting two closures:
func RequestID() server.Middleware {
return server.MiddlewareFromFunc(func(
w http.ResponseWriter,
r *http.Request,
next server.HandlerFunc,
) error {
ctx := context.WithValue(r.Context(), requestIDKey{}, newRequestID())
return next(w, r.WithContext(ctx))
})
}
type MiddlewareFunc ¶
type MiddlewareFunc func(w http.ResponseWriter, r *http.Request, next HandlerFunc) error
MiddlewareFunc is an inline middleware signature that receives the next handler alongside the request, removing the double-closure boilerplate of the bare Middleware type. Convert it with MiddlewareFromFunc.
type NamedMiddleware ¶
type NamedMiddleware interface {
Name() string
Middleware() Middleware
}
NamedMiddleware is a middleware that carries a stable identity. It fits a plugin-style architecture where middleware are discovered and registered dynamically, and the name is useful for logging, ordering, or deduplication.
type OpenAPIInfo ¶
type Operation ¶
type Operation struct {
OperationID string
Method string
Path string
Summary string
Description string
Tags []string
// Security lists the security requirements for this operation. Each entry
// is a set of scheme names (referencing schemes registered via
// [API.AddSecurityScheme]) that must all be satisfied; multiple entries
// are alternatives (logical OR). The value for each scheme is the list of
// required OAuth2 scopes, or an empty slice for non-OAuth2 schemes. Use
// [SecurityRequirement] to build entries.
Security []SecurityRequirement
DefaultStatus int
Deprecated bool
SkipValidateRequest bool
}
type RegisteredOperation ¶
type RequiredJSONField ¶
func RequiredJSONFields ¶
func RequiredJSONFields(t reflect.Type, pointerPrefix, pathPrefix []string) []RequiredJSONField
type RouteOption ¶
type RouteOption func(*routeOptions)
RouteOption customizes the registration of an individual route. Options are accepted by the verb helpers ([Group.GET], [Group.POST], ...), [Group.Handle], [Group.HandleE], and the typed Register/RegisterE functions.
func WithMaxBodyBytes ¶
func WithMaxBodyBytes(n int64) RouteOption
WithMaxBodyBytes overrides the router-wide request body size limit (APIConfig.MaxRequestBodyBytes) for a single route. A positive value caps the body at that many bytes; a value of 0 removes the limit for the route entirely. This is useful when most endpoints want a small default but a specific endpoint (a file upload, a large model prompt) needs a different ceiling:
server.Register(api, uploadOp, uploadHandler, server.WithMaxBodyBytes(100<<20), // 100 MiB )
func WithMiddleware ¶
func WithMiddleware(mw ...Middleware) RouteOption
WithMiddleware attaches middleware to a single route. The middleware run after any root- and group-level middleware and immediately before the handler, in the order given:
server.Register(api, op, handler,
server.WithMiddleware(middleware.RequireScope("llm:chat")),
)
func WithRequestContentTypes ¶
func WithRequestContentTypes(mediaTypes ...string) RouteOption
WithRequestContentTypes restricts a typed route's non-multipart request body codecs to the given media types. Each media type must be registered in APIConfig.Codecs. Routes without this option allow every configured codec.
func WithResponseContentTypes ¶
func WithResponseContentTypes(mediaTypes ...string) RouteOption
WithResponseContentTypes restricts a typed route's successful response body codecs to the given media types. Each media type must be registered in APIConfig.Codecs. Routes without this option allow every configured codec.
type RouteTarget ¶
type RouteTarget interface {
// contains filtered or unexported methods
}
RouteTarget is what Register / RegisterStream register against: a place to attach the composed handler (handleRoute) plus the shared OpenAPI/operation state to document it in. Both API (registering at the root) and APIGroup (registering under a prefix) satisfy it, so the typed registration functions accept either.
type SSEEvent ¶
type SSEEvent struct {
// Data is the event payload. See [SSEEvent] for encoding rules.
Data any
// ID sets the event's "id" field, used by clients as the
// Last-Event-ID on reconnect. Optional.
ID string
// Event sets the event's "event" field (the event type). Optional;
// defaults to "message" on the client when empty.
Event string
// Retry, when > 0, sets the client's reconnection time in milliseconds.
Retry int
}
SSEEvent is a single Server-Sent Event frame.
Data is encoded as follows: a string or []byte is written verbatim; nil emits no data field; any other value is marshaled to JSON. Multi-line data is split across multiple "data:" lines per the SSE specification.
type SecurityRequirement ¶
SecurityRequirement maps security scheme names to the scopes they require for an operation. An empty (or nil) SecurityRequirement documents that the operation may be called without authentication.
type SecurityScheme ¶
type SecurityScheme = openapi.SecurityScheme
SecurityScheme is an alias for openapi.SecurityScheme, re-exported so most applications can declare authentication without importing the openapi package directly. Prefer the constructors APIKeyScheme, BearerScheme, and BasicScheme for the common cases.
func APIKeyScheme ¶
func APIKeyScheme(parameterName, in string) *SecurityScheme
APIKeyScheme describes an API key carried in a header, query parameter, or cookie. in must be one of "header", "query", or "cookie".
func BasicScheme ¶
func BasicScheme() *SecurityScheme
BasicScheme describes HTTP Basic authentication.
func BearerScheme ¶
func BearerScheme(bearerFormat string) *SecurityScheme
BearerScheme describes an HTTP bearer-token scheme (the Authorization: Bearer <token> header). bearerFormat is an optional, informational hint such as "JWT"; pass "" to omit it.
type ServeMuxAdapter ¶
type ServeMuxAdapter struct {
// contains filtered or unexported fields
}
ServeMuxAdapter routes with the standard library's http.ServeMux (Go 1.22+), which already supports method matching, "{name}" path parameters, and "{name...}" trailing wildcards — and populates (*http.Request).PathValue, exactly what tyche's binders read. That makes it a drop-in with no changes to the codec layer.
func NewServeMuxAdapter ¶
func NewServeMuxAdapter() *ServeMuxAdapter
func (*ServeMuxAdapter) Handle ¶
func (a *ServeMuxAdapter) Handle(method, path string, h http.Handler)
func (*ServeMuxAdapter) ServeHTTP ¶
func (a *ServeMuxAdapter) ServeHTTP(w http.ResponseWriter, r *http.Request)
func (*ServeMuxAdapter) SetFallback ¶
func (a *ServeMuxAdapter) SetFallback(notFound, methodNotAllowed http.Handler)
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
func (*Server) ListenAndServe ¶
func (*Server) ListenAndServeTLS ¶
type Stream ¶
type Stream[O any] struct { // contains filtered or unexported fields }
Stream is a type-safe view over an EventStream whose data frames are values of type O. It is the stream type passed to a StreamHandler; for raw access (custom event IDs, retry hints, comments) use Stream.Raw.
func (*Stream[O]) Raw ¶
func (s *Stream[O]) Raw() *EventStream
Raw returns the underlying EventStream for full control over framing.
type StreamHandler ¶
StreamHandler handles a typed streaming request. The input I is parsed and validated from the request like any typed handler; the handler then writes events of type O to the provided Stream. O also documents the JSON shape of each event's data frame in the generated OpenAPI specification.
type ValidationError ¶
type ValidationError = validation.Error
type ValidationProblem ¶
type ValidationProblem = validation.Problem
type ValidationSubject ¶
type ValidationSubject = validation.Subject
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package apidocs mounts OpenAPI schema endpoints and pluggable API documentation UIs.
|
Package apidocs mounts OpenAPI schema endpoints and pluggable API documentation UIs. |
|
Package openapi provides the schema and registry types used to build OpenAPI documents for typed server routes.
|
Package openapi provides the schema and registry types used to build OpenAPI documents for typed server routes. |
|
Package plugins provides production-ready middleware for tyche APIs — recoverer, request ID, real IP, logging, timeout, rate limiting, CORS, security headers, gzip/brotli compression, and instrumentation — applied with api.Use (handler middleware) or api.UseHTTP (edge middleware).
|
Package plugins provides production-ready middleware for tyche APIs — recoverer, request ID, real IP, logging, timeout, rate limiting, CORS, security headers, gzip/brotli compression, and instrumentation — applied with api.Use (handler middleware) or api.UseHTTP (edge middleware). |
|
Package servertest provides helpers for testing tyche routers and handlers with the standard library's httptest, removing the boilerplate of building requests and unwrapping the standard DataResponse envelope.
|
Package servertest provides helpers for testing tyche routers and handlers with the standard library's httptest, removing the boilerplate of building requests and unwrapping the standard DataResponse envelope. |
|
Package validation provides shared rule parsing and runtime validation helpers used by server request parsing, OpenAPI generation, and servergen.
|
Package validation provides shared rule parsing and runtime validation helpers used by server request parsing, OpenAPI generation, and servergen. |