server

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 31, 2026 License: Apache-2.0 Imports: 25 Imported by: 0

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

View Source
const (
	ValidationSubjectString     = validation.SubjectString
	ValidationSubjectNumber     = validation.SubjectNumber
	ValidationSubjectCollection = validation.SubjectCollection
)
View Source
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

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

func DecodeRequestJSONBodyFast(req *http.Request, dst any) error

func DecodeRequestJSONBodyStrictFast

func DecodeRequestJSONBodyStrictFast(req *http.Request, dst any, bodyRequired bool, required []RequiredJSONField) error

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

func EnsureMultipartForm(req *http.Request) error

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 EnsureSingleJSONValue(decoder *json.Decoder) error

func GeneratedTypeKey

func GeneratedTypeKey(t reflect.Type) string

func GetCookie

func GetCookie(r *http.Request, name string) (string, error)

func GetCookieOr

func GetCookieOr(r *http.Request, name, defaultValue string) string

func HasPathTraversal

func HasPathTraversal(path string) bool

func JoinValidationPointer

func JoinValidationPointer(base string, parts ...string) string

func NegotiateResponseContentType

func NegotiateResponseContentType(req *http.Request, mediaTypes ...string) error

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 Param

func Param(req *http.Request, name string) string

func ParseRequest

func ParseRequest[I any](req *http.Request) (*I, error)

func ParseRequestWithCodecs

func ParseRequestWithCodecs[I any](req *http.Request, codecs []Codec) (*I, error)

func ReadMultipartFiles

func ReadMultipartFiles(req *http.Request, name string) ([]*multipart.FileHeader, bool, error)

ReadMultipartFiles reads all uploaded files for a multipart file field.

func ReadMultipartFormValues

func ReadMultipartFormValues(req *http.Request, name string) ([]string, bool, error)

ReadMultipartFormValues reads all values for a multipart form field.

func ReadRequestJSONBody

func ReadRequestJSONBody(req *http.Request) ([]byte, error)

func ReadRequestJSONBodyFast

func ReadRequestJSONBodyFast(req *http.Request) ([]byte, error)

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

func RoutePattern(req *http.Request) string

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 SchemaComponentName(t reflect.Type) string

func ServerPathToOpenAPIPath

func ServerPathToOpenAPIPath(path string) string

func SetCookie

func SetCookie(w http.ResponseWriter, cfg CookieConfig)

func SetCookieDefault

func SetCookieDefault(w http.ResponseWriter, name, value string)

func SplitRouteFast

func SplitRouteFast(route string) []string

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 UseJSONCodecForRequest(req *http.Request, codecs []Codec) (bool, error)

func UseJSONCodecForResponse

func UseJSONCodecForResponse(req *http.Request, codecs []Codec) (bool, error)

func ValidateJSONContentType

func ValidateJSONContentType(contentType string) error

func ValidateRequiredJSONFields

func ValidateRequiredJSONFields(body []byte, required []RequiredJSONField) error

func ValidateUUID

func ValidateUUID(value string) bool

func ValidationStringLength

func ValidationStringLength(value string) int

func Wildcard

func Wildcard(req *http.Request) string

func WriteJSON

func WriteJSON(w http.ResponseWriter, status int, v any) error

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 WriteSuccessWithCodecs(w http.ResponseWriter, req *http.Request, status int, data any, codecs []Codec) error

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

func NewAPI(adapter Adapter, cfg ...APIConfig) *API

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

func (a *API) Codecs() []Codec

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

func (a *API) Mount(prefix string, handler http.Handler) error

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

func (a *API) MountOpenAPI(path string) error

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

func (a *API) OpenAPI() *openapi.OpenAPI

OpenAPI returns the underlying document.

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

func (a *API) SchemaRegistry() *openapi.Registry

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

func (a *API) SetMethodNotAllowedHandler(h http.Handler)

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

func (a *API) SetNotFoundHandler(h http.Handler)

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

func (g *APIGroup) Group(prefix string, mw ...Middleware) *APIGroup

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

func DefaultConfig(address string) Config

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.

func (ContextKey[T]) WithValue

func (key ContextKey[T]) WithValue(ctx context.Context, value T) context.Context

WithValue returns a copy of ctx carrying value associated with this key.

type CookieConfig

type CookieConfig struct {
	Expires  time.Time
	Name     string
	Value    string
	Path     string
	Domain   string
	MaxAge   int
	SameSite http.SameSite
	Secure   bool
	HTTPOnly bool
}

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 GeneratedRouteCodec struct {
	Parse           func(*http.Request) (any, error)
	Write           func(http.ResponseWriter, *http.Request, any) error
	ParseWithCodecs func(*http.Request, []Codec) (any, error)
	WriteWithCodecs func(http.ResponseWriter, *http.Request, any, []Codec) error
}

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 HTTPError

type HTTPError struct {
	Message    string
	StatusCode int
	Silent     bool
}

func NewHTTPError

func NewHTTPError(statusCode int, message string) HTTPError

func SilentHTTPError

func SilentHTTPError(statusCode int, message string) HTTPError

func (HTTPError) Error

func (e HTTPError) Error() string

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

func (JSONCodec) AcquireGeneratedSuccessBuffer() *[]byte

AcquireGeneratedSuccessBuffer returns a scratch buffer for generated JSON success response writers. Release it with ReleaseGeneratedSuccessBuffer.

func (JSONCodec) AppendBool

func (JSONCodec) AppendBool(dst []byte, v bool) []byte

func (JSONCodec) AppendFloat

func (JSONCodec) AppendFloat(dst []byte, v float64) []byte

func (JSONCodec) AppendInt

func (JSONCodec) AppendInt(dst []byte, v int64) []byte

func (JSONCodec) AppendString

func (JSONCodec) AppendString(dst []byte, v string) []byte

func (JSONCodec) AppendUint

func (JSONCodec) AppendUint(dst []byte, v uint64) []byte

func (JSONCodec) DecodeRequest

func (JSONCodec) DecodeRequest(req *http.Request, dst any) error

func (JSONCodec) DecodeRequestStrict

func (JSONCodec) DecodeRequestStrict(req *http.Request, dst any, bodyRequired bool, required []RequiredJSONField) error

func (JSONCodec) EncodeSuccess

func (JSONCodec) EncodeSuccess(w http.ResponseWriter, status int, data any) error

func (JSONCodec) MediaType

func (JSONCodec) MediaType() string

func (JSONCodec) ReadRequest

func (JSONCodec) ReadRequest(req *http.Request) ([]byte, error)

func (JSONCodec) ReleaseGeneratedSuccessBuffer

func (JSONCodec) ReleaseGeneratedSuccessBuffer(buf *[]byte)

func (JSONCodec) WriteGeneratedSuccess

func (JSONCodec) WriteGeneratedSuccess(w http.ResponseWriter, status int, body []byte) error

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 OpenAPIInfo struct {
	Title       string
	Description string
	Version     string
}

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 RegisteredOperation struct {
	InputType   reflect.Type
	OutputType  reflect.Type
	Method      string
	Path        string
	Summary     string
	Description string
	OperationID string
	Tags        []string
}

type RequiredJSONField

type RequiredJSONField struct {
	Pointer string
	Path    []string
}

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 WithPaginationConfig added in v1.1.0

func WithPaginationConfig(config pagination.Config) RouteOption

WithPaginationConfig applies cursor-pagination defaults and bounds to typed routes that include pagination.Params. Routes without pagination inputs are unaffected.

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

type SecurityRequirement = map[string][]string

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 ServeHTTPMiddleware

type ServeHTTPMiddleware func(next http.Handler) http.Handler

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 New

func New(cfg Config, handler http.Handler) *Server

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

func (*Server) ListenAndServeTLS

func (s *Server) ListenAndServeTLS(certFile, keyFile string) error

func (*Server) Run

func (s *Server) Run() error

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

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]) Comment

func (s *Stream[O]) Comment(text string) error

Comment writes an SSE comment line, commonly used as a keep-alive ping.

func (*Stream[O]) Context

func (s *Stream[O]) Context() context.Context

Context returns the request context; stop sending when it is done.

func (*Stream[O]) Raw

func (s *Stream[O]) Raw() *EventStream

Raw returns the underlying EventStream for full control over framing.

func (*Stream[O]) Send

func (s *Stream[O]) Send(data O) error

Send marshals data to JSON and emits it as a single SSE data frame.

func (*Stream[O]) SendEvent

func (s *Stream[O]) SendEvent(event string, data O) error

SendEvent emits data as a named event (the SSE "event" field).

type StreamHandler

type StreamHandler[I, O any] func(ctx context.Context, in *I, stream *Stream[O]) error

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 TypedHandler

type TypedHandler[I, O any] func(context.Context, *I) (*O, error)

type ValidationError

type ValidationError = validation.Error

type ValidationProblem

type ValidationProblem = validation.Problem

type ValidationSubject

type ValidationSubject = validation.Subject

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.

Jump to

Keyboard shortcuts

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