Documentation
¶
Overview ¶
Package ohm provides the HTTP application primitives for the Ohm web framework.
Index ¶
- Constants
- Variables
- func DefaultErrorHandler(req *Request, err error)
- func Do(ctx context.Context, name string, fn func(context.Context) error) error
- func ErrorResponse(err error) (int, string)
- func Observe[T any](ctx context.Context, name string, fn func(context.Context) (T, error), ...) (T, error)
- func ObserveDo(ctx context.Context, name string, fn func(context.Context) error, ...) error
- func RenderHTML(w http.ResponseWriter, r *http.Request, status int, html HTML) error
- func RequestID(ctx context.Context) (string, bool)
- func RouteParam(r *http.Request, key string) string
- func RouteParams(r *http.Request) map[string]string
- func RoutePattern(r *http.Request) string
- func SetStatus(r *http.Request, status int)
- func Span[T any](ctx context.Context, name string, fn func(context.Context) (T, error)) (T, error)
- func TraceLogHandler(next slog.Handler) slog.Handler
- type App
- func (a *App) AllowedMethods(path string) []string
- func (a *App) Delete(pattern string, handler Handler)
- func (a *App) Get(pattern string, handler Handler)
- func (a *App) GetHTTP(pattern string, handler http.Handler)
- func (a *App) HTTPHandler() http.Handler
- func (a *App) Handle(method string, pattern string, handler Handler)
- func (a *App) HandleHTTP(method string, pattern string, handler http.Handler)
- func (a *App) Head(pattern string, handler Handler)
- func (a *App) HeadHTTP(pattern string, handler http.Handler)
- func (a *App) MethodNotAllowed(handler MethodNotAllowedHandler)
- func (a *App) NotFound(handler http.HandlerFunc)
- func (a *App) Patch(pattern string, handler Handler)
- func (a *App) Post(pattern string, handler Handler)
- func (a *App) Put(pattern string, handler Handler)
- func (a *App) Routes() ([]Route, error)
- func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (a *App) Static(pattern string, root string)
- func (a *App) Use(middlewares ...Middleware)
- type Binder
- type BoolValidation
- type DirSink
- type ErrorHandler
- type ErrorParam
- type Errors
- func (e Errors) All() []ValidationError
- func (e Errors) Any() bool
- func (e Errors) Err() error
- func (e Errors) Error() string
- func (e Errors) First(field string) (ValidationError, bool)
- func (e Errors) For(field string) Errors
- func (e Errors) Is(target error) bool
- func (e Errors) Len() int
- func (e Errors) Messages(field string) []string
- type FlightRecorder
- type FlightRecorderOption
- type HTML
- type HTMLFragment
- type HTMLFunc
- type HTMLView
- type HTTPError
- type Handler
- type IntValidation
- type MethodNotAllowedHandler
- type Middleware
- type ObserveOption
- type Option
- type Renderer
- type Request
- func (r *Request) Bind(v Binder) error
- func (r *Request) Context() context.Context
- func (r *Request) Decode(v any) error
- func (r *Request) HTML(status int, html HTML) error
- func (r *Request) HTTPRequest() *http.Request
- func (r *Request) JSON(status int, v any)
- func (r *Request) NoContent()
- func (r *Request) Param(key string) string
- func (r *Request) PlainText(status int, text string)
- func (r *Request) Redirect(status int, url string)
- func (r *Request) Render(v Renderer) error
- func (r *Request) ResponseWriter() http.ResponseWriter
- func (r *Request) RoutePattern() string
- type Route
- type Sink
- type SliceValidation
- type StringValidation
- type TimeValidation
- type Validatable
- type Validation
- func (v *Validation) Add(field string, code string, message string, params ...ErrorParam)
- func (v *Validation) Bool(field string, value bool) BoolValidation
- func (v *Validation) Errors() Errors
- func (v *Validation) Int(field string, value int) IntValidation
- func (v *Validation) Nested(field string, value Validatable)
- func (v *Validation) Slice(field string, value any) SliceValidation
- func (v *Validation) String(field string, value string) StringValidation
- func (v *Validation) Time(field string, value time.Time) TimeValidation
- type ValidationError
Examples ¶
Constants ¶
const ( ValidationCodeRequired = "required" ValidationCodeTooShort = "too_short" ValidationCodeTooLong = "too_long" ValidationCodeTooSmall = "too_small" ValidationCodeTooLarge = "too_large" ValidationCodeAccepted = "accepted" ValidationCodeRejected = "rejected" ValidationCodeInvalid = "invalid" )
Validation error codes used by Ohm's built-in validators.
const RequestIDHeader = "X-Request-ID"
RequestIDHeader is the default HTTP header for request ids.
Variables ¶
var ErrValidation = errors.New("validation failed")
ErrValidation identifies a validation failure.
Functions ¶
func DefaultErrorHandler ¶
DefaultErrorHandler renders handler errors as plain text.
func Do ¶
Do runs fn inside a new span named name for side-effecting work that returns only an error. It is the result-less companion to Span:
err := ohm.Do(ctx, "send welcome email", func(ctx context.Context) error {
return mailer.Send(ctx, welcome)
})
func ErrorResponse ¶
ErrorResponse returns the safe HTTP status and public message for err.
func Observe ¶ added in v0.9.0
func Observe[T any](ctx context.Context, name string, fn func(context.Context) (T, error), opts ...ObserveOption) (T, error)
Observe runs fn and only emits a retrospective span when the operation fails or matches a configured observation policy, such as SlowAfter. Fast successful operations are left out of the trace so high-volume helper calls do not drown out the request span.
Unlike Span, Observe does not place a live child span on the context passed to fn. Downstream work therefore continues to see ctx's existing span. Use Span instead when nested work must propagate under a child span while it runs.
When Observe emits a span, it records the operation's real start and end times with OpenTelemetry timestamps. Returned errors mark the span failed and record only the error's Go type, never the raw error text.
Example ¶
ctx := context.Background()
user, err := Observe(ctx, "load user", func(ctx context.Context) (string, error) {
return "ada", nil
}, SlowAfter(50*time.Millisecond))
if err != nil {
return
}
_ = user
func ObserveDo ¶ added in v0.9.0
func ObserveDo(ctx context.Context, name string, fn func(context.Context) error, opts ...ObserveOption) error
ObserveDo runs fn through Observe for side-effecting work that returns only an error.
func RenderHTML ¶
RenderHTML renders content as an HTML response with status.
func RouteParam ¶
RouteParam returns a route parameter by name.
func RouteParams ¶
RouteParams returns the matched route parameters.
func RoutePattern ¶
RoutePattern returns the matched route pattern when available.
func Span ¶
Span runs fn inside a new span named name and returns fn's result and error unchanged. It ends the span when fn returns and, on error, marks the span failed, so manual instrumentation reads as ordinary code with no start/end/record/status boilerplate:
user, err := ohm.Span(ctx, "load user", func(ctx context.Context) (User, error) {
return store.User(ctx, id)
})
On error the span status is set to error and the error's Go type is recorded as the error.type attribute. The raw error text is deliberately not sent to the tracing backend, since it may hold sensitive data; the full error is available through correlated logs, consistent with the framework's scrubbing policy. To attach additional attributes, take the span from the context passed to fn with trace.SpanFromContext.
The span is created from the globally configured OpenTelemetry tracer, which is a no-op until an application installs a provider, so Span is safe to use unconditionally.
func TraceLogHandler ¶
TraceLogHandler wraps next so every log record carries the active trace and span ids when a valid span context is present on the record context.
It composes with any other handler, including the scrubbing handler, and is a no-op when no span is active. Because Ohm logging already passes the request context to slog, this correlates logs with traces without any change to application logging code.
Types ¶
type App ¶
type App struct {
// contains filtered or unexported fields
}
App is an Ohm HTTP application.
func (*App) AllowedMethods ¶
AllowedMethods returns HTTP methods that match path.
func (*App) HTTPHandler ¶
HTTPHandler returns the underlying HTTP handler.
func (*App) HandleHTTP ¶
HandleHTTP registers handler for method and pattern.
func (*App) MethodNotAllowed ¶
func (a *App) MethodNotAllowed(handler MethodNotAllowedHandler)
MethodNotAllowed configures the handler used when only the method is missing.
func (*App) NotFound ¶
func (a *App) NotFound(handler http.HandlerFunc)
NotFound configures the handler used when no route matches.
func (*App) ServeHTTP ¶
func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP serves HTTP requests.
func (*App) Use ¶
func (a *App) Use(middlewares ...Middleware)
Use appends middleware to the app router.
type BoolValidation ¶ added in v0.10.0
type BoolValidation struct {
// contains filtered or unexported fields
}
BoolValidation validates a bool field.
func (BoolValidation) Accepted ¶ added in v0.10.0
func (v BoolValidation) Accepted() BoolValidation
Accepted requires the value to be true.
func (BoolValidation) Rejected ¶ added in v0.10.0
func (v BoolValidation) Rejected() BoolValidation
Rejected requires the value to be false.
type DirSink ¶
type DirSink struct {
Dir string
}
DirSink writes snapshots as files under Dir, creating it as needed.
type ErrorHandler ¶
ErrorHandler handles errors returned by Ohm handlers.
type ErrorParam ¶ added in v0.10.0
ErrorParam is a named value attached to a validation error.
type Errors ¶ added in v0.10.0
type Errors []ValidationError
Errors is a collection of validation failures.
func Validate ¶ added in v0.10.0
func Validate(v Validatable) Errors
Validate runs v's validation rules and returns the collected errors.
Example ¶
form := exampleSignupForm{
Email: "",
Age: 12,
}
errs := Validate(form)
for _, err := range errs.All() {
fmt.Println(err.Field, err.Code, err.Message)
}
Output: email required is required age too_small must be at least 13
func (Errors) All ¶ added in v0.10.0
func (e Errors) All() []ValidationError
All returns a copy of all validation errors.
func (Errors) First ¶ added in v0.10.0
func (e Errors) First(field string) (ValidationError, bool)
First returns the first validation error for field.
type FlightRecorder ¶
type FlightRecorder struct {
// contains filtered or unexported fields
}
FlightRecorder captures the recent Go execution-trace window on demand.
It wraps runtime/trace.FlightRecorder, which keeps a low-overhead rolling window of execution-trace data in memory. Ohm snapshots that window on rare, high-value events — recovered panics and slow requests — so the runtime behavior leading up to an incident is available for go tool trace without always-on tracing. Snapshots are correlated with logs and OpenTelemetry spans by id, never converted into spans.
At most one flight recorder may be active in a process. Construct one, Start it during startup, add FlightRecording to the middleware stack, and register Stop as a server shutdown hook:
recorder := ohm.NewFlightRecorder(ohm.WithSlowRequestThreshold(time.Second))
if err := recorder.Start(); err != nil {
return err
}
application.Use(ohm.Tracing(), ohm.RequestLogger(logger), ohm.Recoverer(logger), ohm.FlightRecording(recorder))
// cli.ServerCommand(handler, cli.WithShutdownHook(recorder.Stop))
func NewFlightRecorder ¶
func NewFlightRecorder(opts ...FlightRecorderOption) *FlightRecorder
NewFlightRecorder creates a flight recorder. It does not begin recording until Start is called.
func (*FlightRecorder) Start ¶
func (f *FlightRecorder) Start() error
Start begins recording the execution-trace window.
type FlightRecorderOption ¶
type FlightRecorderOption func(*flightRecorderConfig)
FlightRecorderOption configures a FlightRecorder.
func WithFlightRecorderLogger ¶
func WithFlightRecorderLogger(logger *slog.Logger) FlightRecorderOption
WithFlightRecorderLogger sets the logger used to report snapshot activity.
func WithSlowRequestThreshold ¶
func WithSlowRequestThreshold(d time.Duration) FlightRecorderOption
WithSlowRequestThreshold enables slow-request snapshots for requests whose duration meets or exceeds d. A non-positive d disables the slow-request trigger, leaving only panic snapshots.
func WithTraceSink ¶
func WithTraceSink(sink Sink) FlightRecorderOption
WithTraceSink sets where snapshots are written. The default writes files under tmp/traces.
func WithTraceWindow ¶
func WithTraceWindow(minAge time.Duration, maxBytes uint64) FlightRecorderOption
WithTraceWindow sets the recorder's window bounds. minAge is the lower bound on how far back the window reaches; maxBytes caps its size. Zero values use the runtime defaults.
type HTML ¶ added in v0.9.0
HTML renders a server-rendered HTML response body.
func HTMLTemplate ¶ added in v0.9.0
func HTMLTemplate(t *htmltemplate.Template, name string, data any) HTML
HTMLTemplate renders a named html/template template with data.
type HTMLFragment ¶ added in v0.9.0
type HTMLFragment struct {
// contains filtered or unexported fields
}
HTMLFragment describes a named HTML fragment for a page region.
func Fragment ¶ added in v0.9.0
func Fragment(target string, html HTML) HTMLFragment
Fragment creates an HTML fragment for target.
func (HTMLFragment) HTML ¶ added in v0.9.0
func (f HTMLFragment) HTML() HTML
HTML returns the HTML rendered for this fragment.
func (HTMLFragment) Target ¶ added in v0.9.0
func (f HTMLFragment) Target() string
Target returns the page-region target name for this fragment.
type HTMLView ¶ added in v0.9.0
type HTMLView struct {
// contains filtered or unexported fields
}
HTMLView describes a server-rendered HTML response with optional fragments.
func View ¶ added in v0.9.0
func View(full HTML, fragments ...HTMLFragment) HTMLView
View creates an HTMLView from a full response and optional named fragments.
func (HTMLView) Fragment ¶ added in v0.9.0
func (v HTMLView) Fragment(target string) (HTMLFragment, bool)
Fragment returns the fragment with target when one exists.
func (HTMLView) Fragments ¶ added in v0.9.0
func (v HTMLView) Fragments() []HTMLFragment
Fragments returns the fragments declared for this view.
func (HTMLView) Full ¶ added in v0.9.0
Full returns the HTML rendered for normal full-page responses.
func (HTMLView) SingleFragment ¶ added in v0.9.0
func (v HTMLView) SingleFragment() (HTMLFragment, bool)
SingleFragment returns the only fragment when the view has exactly one.
type HTTPError ¶
HTTPError is an error with an HTTP response status.
func NewHTTPError ¶
NewHTTPError creates an HTTPError.
type IntValidation ¶ added in v0.10.0
type IntValidation struct {
// contains filtered or unexported fields
}
IntValidation validates an int field.
func (IntValidation) Between ¶ added in v0.10.0
func (v IntValidation) Between(min int, max int) IntValidation
Between requires a value between min and max.
func (IntValidation) Max ¶ added in v0.10.0
func (v IntValidation) Max(n int) IntValidation
Max requires a value less than or equal to n.
func (IntValidation) Min ¶ added in v0.10.0
func (v IntValidation) Min(n int) IntValidation
Min requires a value greater than or equal to n.
type MethodNotAllowedHandler ¶
type MethodNotAllowedHandler func(http.ResponseWriter, *http.Request, []string)
MethodNotAllowedHandler handles requests whose path matches other methods.
type Middleware ¶
Middleware wraps an HTTP handler.
func FlightRecording ¶
func FlightRecording(recorder *FlightRecorder) Middleware
FlightRecording returns middleware that snapshots the execution-trace window on a recovered panic or a slow request. Place it innermost, below Recoverer, so a panic snapshot is taken before Recoverer renders the response. A nil recorder yields a pass-through middleware.
func Recoverer ¶
func Recoverer(logger *slog.Logger) Middleware
Recoverer recovers panics, logs a redacted panic report, and renders a 500 response.
func RequestLogger ¶
func RequestLogger(logger *slog.Logger) Middleware
RequestLogger logs one structured event for each completed request.
func Tracing ¶
func Tracing() Middleware
Tracing returns middleware that records one server span per request using the globally configured OpenTelemetry tracer.
Until an application installs a tracer provider (see the ohm/otel package) the global tracer is a no-op, so this middleware is safe to keep in every stack and adds negligible overhead when tracing is disabled. The span is placed on the request context, so handlers and ohm.Span observe it without any tracer plumbing in application code. Span name and route attribute are set from the matched route once routing completes, and the response status is recorded when the handler returns.
type ObserveOption ¶ added in v0.9.0
type ObserveOption func(*observeConfig)
ObserveOption configures Observe.
func SlowAfter ¶ added in v0.9.0
func SlowAfter(d time.Duration) ObserveOption
SlowAfter emits an observed span when fn takes at least d. Non-positive durations disable slow-success observation; returned errors are still observed.
type Option ¶
type Option func(*App)
Option configures an App.
func WithErrorHandler ¶
func WithErrorHandler(handler ErrorHandler) Option
WithErrorHandler configures how handler errors are rendered.
type Renderer ¶
type Renderer interface {
Render(http.ResponseWriter, *http.Request) error
}
Renderer writes a structured response.
type Request ¶
type Request struct {
// contains filtered or unexported fields
}
Request is the Ohm request and response boundary passed to handlers.
func (*Request) HTTPRequest ¶
HTTPRequest returns the underlying HTTP request escape hatch.
func (*Request) ResponseWriter ¶
func (r *Request) ResponseWriter() http.ResponseWriter
ResponseWriter returns the underlying HTTP response writer escape hatch.
func (*Request) RoutePattern ¶
RoutePattern returns the matched route pattern when available.
type Sink ¶
type Sink interface {
// Create opens a writer for a snapshot identified by name. The caller closes
// the returned writer.
Create(name string) (io.WriteCloser, error)
}
Sink stores captured execution-trace snapshots.
type SliceValidation ¶ added in v0.10.0
type SliceValidation struct {
// contains filtered or unexported fields
}
SliceValidation validates a slice or array field.
func (SliceValidation) Length ¶ added in v0.10.0
func (v SliceValidation) Length(min int, max int) SliceValidation
Length requires a length between min and max.
func (SliceValidation) Max ¶ added in v0.10.0
func (v SliceValidation) Max(n int) SliceValidation
Max requires at most n items.
func (SliceValidation) Min ¶ added in v0.10.0
func (v SliceValidation) Min(n int) SliceValidation
Min requires at least n items.
func (SliceValidation) Presence ¶ added in v0.10.0
func (v SliceValidation) Presence() SliceValidation
Presence requires at least one item.
type StringValidation ¶ added in v0.10.0
type StringValidation struct {
// contains filtered or unexported fields
}
StringValidation validates a string field.
func (StringValidation) Length ¶ added in v0.10.0
func (v StringValidation) Length(min int, max int) StringValidation
Length requires a string length between min and max.
func (StringValidation) Max ¶ added in v0.10.0
func (v StringValidation) Max(n int) StringValidation
Max requires at most n characters.
func (StringValidation) Min ¶ added in v0.10.0
func (v StringValidation) Min(n int) StringValidation
Min requires at least n characters when the string is not blank.
func (StringValidation) Presence ¶ added in v0.10.0
func (v StringValidation) Presence() StringValidation
Presence requires a non-blank string.
type TimeValidation ¶ added in v0.10.0
type TimeValidation struct {
// contains filtered or unexported fields
}
TimeValidation validates a time field.
func (TimeValidation) After ¶ added in v0.10.0
func (v TimeValidation) After(boundary time.Time) TimeValidation
After requires a time after boundary.
func (TimeValidation) Before ¶ added in v0.10.0
func (v TimeValidation) Before(boundary time.Time) TimeValidation
Before requires a time before boundary.
func (TimeValidation) Presence ¶ added in v0.10.0
func (v TimeValidation) Presence() TimeValidation
Presence requires a non-zero time.
type Validatable ¶ added in v0.10.0
type Validatable interface {
Validate(*Validation)
}
Validatable is implemented by values that can validate themselves.
type Validation ¶ added in v0.10.0
type Validation struct {
// contains filtered or unexported fields
}
Validation collects structured validation errors.
func NewValidation ¶ added in v0.10.0
func NewValidation() *Validation
NewValidation creates an empty validation collector.
func (*Validation) Add ¶ added in v0.10.0
func (v *Validation) Add(field string, code string, message string, params ...ErrorParam)
Add records a custom validation error.
func (*Validation) Bool ¶ added in v0.10.0
func (v *Validation) Bool(field string, value bool) BoolValidation
Bool validates a bool field.
func (*Validation) Errors ¶ added in v0.10.0
func (v *Validation) Errors() Errors
Errors returns the collected validation errors.
func (*Validation) Int ¶ added in v0.10.0
func (v *Validation) Int(field string, value int) IntValidation
Int validates an int field.
func (*Validation) Nested ¶ added in v0.10.0
func (v *Validation) Nested(field string, value Validatable)
Nested runs validation for v under field's prefix.
func (*Validation) Slice ¶ added in v0.10.0
func (v *Validation) Slice(field string, value any) SliceValidation
Slice validates a slice or array field.
func (*Validation) String ¶ added in v0.10.0
func (v *Validation) String(field string, value string) StringValidation
String validates a string field.
func (*Validation) Time ¶ added in v0.10.0
func (v *Validation) Time(field string, value time.Time) TimeValidation
Time validates a time field.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package cli provides lightweight command dispatch and HTTP server lifecycle helpers for Ohm applications.
|
Package cli provides lightweight command dispatch and HTTP server lifecycle helpers for Ohm applications. |
|
cmd
|
|
|
ohm
command
The ohm command runs the Ohm framework CLI.
|
The ohm command runs the Ohm framework CLI. |
|
Package config decodes environment-backed settings into typed Go structs.
|
Package config decodes environment-backed settings into typed Go structs. |
|
Package env parses, loads, and applies Ohm environment files.
|
Package env parses, loads, and applies Ohm environment files. |
|
Package htmx adapts Ohm HTML views to htmx request and response headers.
|
Package htmx adapts Ohm HTML views to htmx request and response headers. |
|
Package migrate provides database migration runners and CLI commands.
|
Package migrate provides database migration runners and CLI commands. |
|
Package ohmcli assembles the Ohm framework command-line interface.
|
Package ohmcli assembles the Ohm framework command-line interface. |
|
Package otel wires OpenTelemetry for an Ohm application.
|
Package otel wires OpenTelemetry for an Ohm application. |
|
Package replay captures and replays HTTP request snapshots for regression tests.
|
Package replay captures and replays HTTP request snapshots for regression tests. |
|
Package scaffold generates Ohm application, handler, migration, resource, and replay-test files.
|
Package scaffold generates Ohm application, handler, migration, resource, and replay-test files. |
|
Package scrub redacts sensitive data from structured values and slog records.
|
Package scrub redacts sensitive data from structured values and slog records. |
|
Package sqltx provides explicit transaction helpers for database/sql.
|
Package sqltx provides explicit transaction helpers for database/sql. |