mux

package module
v0.0.0-...-066a119 Latest Latest
Warning

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

Go to latest
Published: Jul 5, 2022 License: ISC Imports: 22 Imported by: 0

README

mux

Package mux implements HTTP application lifecycle helpers.

Overview

This package centers around the Handler, a flexible implementation of the standard http.Handler interface that is so much more than a HTTP request multiplexer, but less than a framework.

Use of this package gives you the following:

  • request router/dispatcher
  • middleware (top-level and per-route)
  • automatic HEAD responses
  • automatic OPTIONS responses
  • 400 Bad Request responses on decode errors
  • 405 Method Not Allowed responses
  • 406 Not Acceptable plain text error
  • 415 Unsupported Media Type responses on content type errors
  • 422 Unprocessable Entity responses on form validation errors
  • 500 Internal Server Error responses on panic
  • response buffer pool to eliminate partially rendered responses
  • request identifiers for instrumentation
  • locale detection for internationalization
  • export routes to static files
  • request observer hooks
  • health check handler

Individual components of this package are customizable and/or replaceable where possible. Application structure is not imposed. Defaults for a greenfield JSON API are preconfigured.

Route patterns are mapped to by a Router. The Router may also be a Builder or Walker for additional functionality.

HandlerFuncs are like http.HandlerFuncs but return errors that are resolved to HTTP error responses through a Resolver that transforms errors to Error views. The error views are encoded and written as a response.

The error views are encoded with Encode, also available for use within HandlerFuncs for any encoded response. The handler can be configured with an EncoderFunc that negotiates an Encoder from an incoming HTTP request. The default matches on Accept header media types. A request that fails to negotiate an encoder will be served a plain text HTTP 406 Not Acceptable error.

Use Decode to decode incoming request data to a validated data structure. The handler can be configured with a DecoderFunc that negotiates a Decoder from an incoming HTTP request. The default matches Content-Type headers. A request that fails to negotiate a decoder will be served a HTTP 415 Unsupported Media Type error, encoded with the negotiated encoder.

The unique request identifier can be retrieved with RequestID. This may be useful for implementing custom Loggers or Error views.

The detected locale can be retrieved with Locale. The supported locales can be set when creating the handler using WithLocales and defaults to English.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDecodeContentType = errors.New("mux: no decoder matched request")
	ErrDecodeRequestData = errors.New("mux: bad request data for decoder")
)

Decoder errors.

View Source
var ErrBuild = errors.New("mux: named route does not exist")

ErrBuild represents a Builder error.

View Source
var ErrEncodeMatch = errors.New("mux: no encoder matched request")

ErrEncodeMatch indicates that request failed to negotiate an Encoder.

View Source
var ErrNotFound = errors.New("mux: no route matched request")

ErrNotFound represents a HTTP 404 Not Found error.

Functions

func AssetCacheFS

func AssetCacheFS(fs fs.FS) fs.FS

AssetCacheFS returns the fs as an implementation of CacheControlFS. All files will be cached with the "public, max-age=31536000" policy.

func ErrorText

func ErrorText(code int, err error) string

ErrorText returns supplementary message text for errors.

Explicit descriptions are returned for mux errors. The error text is returned for http.StatusUnprocessableEntity status codes and instances of mux.ValidationError. The empty string is returned for unknown errors.

func Locale

func Locale(req *http.Request) language.Tag

Locale returns the best match BCP 47 language tag parsed from the Accept-Language header.

func Param

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

Param returns the named parameter.

func Query

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

Query returns the first query value associated with the given key. If there are no values associated with the key, Query returns the empty string.

func RequestID

func RequestID(req *http.Request) string

RequestID returns the request identifier from the X-Request-ID header. The formatted request sequence number is returned if the header is not set.

func Sequence

func Sequence(req *http.Request) uint64

Sequence returns the request sequence number.

func SetLocale

func SetLocale(req *http.Request, tag language.Tag)

SetLocale sets the BCP 47 language tag on the request context.

Types

type Builder

type Builder interface {
	Build(name string, params Params) (string, error)
}

Builder represents the ability to build routes by name.

type CacheControlFS

type CacheControlFS interface {
	fs.FS
	CacheControl(name string) string
}

CacheControlFS represents the ability to associate a Cache-Control response header with a file name.

type Decoder

type Decoder interface {
	Decode(req *http.Request, form Form) error
}

Decoder represents the ability to decode, sanitize and validate a request body.

type DecoderFunc

type DecoderFunc func(req *http.Request) (Decoder, error)

DecoderFunc represents the ability to negotiate a Decoder from an incoming HTTP request. Return the error ErrDecodeContentType to respond with a 415 Unsupported Media Type error.

func NewContentTypeDecoder

func NewContentTypeDecoder(decoders map[string]Decoder) DecoderFunc

NewContentTypeDecoder returns a DecoderFunc that returns the first negotiated Decoder from the request Content-Type header.

type Encoder

type Encoder interface {
	Encode(w io.Writer, view Viewable) error
	Headers() http.Header
}

Encoder represents the ability to encode HTTP responses.

type EncoderFunc

type EncoderFunc func(req *http.Request) (Encoder, error)

EncoderFunc represents the ability to negotiate an Encoder from an incoming HTTP request. Return the error ErrEncodeMatch to respond with a 406 Not Acceptable error.

func NewAcceptEncoder

func NewAcceptEncoder(encoders map[string]Encoder) EncoderFunc

NewAcceptEncoder returns an EncoderFunc that returns the first Encoder negotiated from the request Accept header.

type ErrMethodNotAllowed

type ErrMethodNotAllowed []string

ErrMethodNotAllowed represents a HTTP 405 Method Not Allowed error.

func (ErrMethodNotAllowed) Error

func (e ErrMethodNotAllowed) Error() string

Error implements the error interface.

type ErrRedirect

type ErrRedirect struct {
	URL  string
	Code int
}

ErrRedirect represents a redirect response.

func (ErrRedirect) Error

func (e ErrRedirect) Error() string

Error implements the error interface.

type Error

type Error interface {
	error
	StatusCode() int
}

Error repesents an error view.

type ErrorView

type ErrorView struct {
	Code      int    `json:"code"`
	Title     string `json:"title"`
	Message   string `json:"message,omitempty"`
	RequestID string `json:"request_id"`
}

ErrorView is the default error view.

func NewErrorView

func NewErrorView(req *http.Request, code int, err error) ErrorView

NewErrorView returns a new ErrorView.

func (ErrorView) Error

func (v ErrorView) Error() string

Error implements the error interface.

func (ErrorView) StatusCode

func (v ErrorView) StatusCode() int

StatusCode implements the mux.Error interface.

type Exporter

type Exporter interface {
	Export(r *Route, b []byte) error
}

Exporter represents a route exporter.

type FileSystemExporter

type FileSystemExporter string

FileSystemExporter is an Exporter implementation that writes to the directory by the string value. The route name is used to determine the exported filenames. An error is returned if an exported file already exists. An empty FileSystemExporter is treated as "dist".

func (FileSystemExporter) Export

func (e FileSystemExporter) Export(r *Route, b []byte) error

Export implements the Exporter interface.

type Form

type Form interface {
	// Validate sanitizes and validates the form.
	Validate() error
}

A Form represents a form with validation.

type Handler

type Handler struct {
	// contains filtered or unexported fields
}

Handler is a http.Handler with application lifecycle helpers.

func New

func New(opts ...Option) *Handler

New returns a new handler.

func (*Handler) Abort

func (h *Handler) Abort(w http.ResponseWriter, req *http.Request, err error)

Abort resolves an error to a view and encodes the response.

func (*Handler) Add

func (h *Handler) Add(pattern string, handler HandlerFunc, opts ...RouteOption) *Route

Add registers a HandlerFunc.

func (*Handler) Build

func (h *Handler) Build(name string, params Params) (string, error)

Build returns the URL for the named route.

func (*Handler) Decode

func (h *Handler) Decode(req *http.Request, form Form) error

Decode decodes, sanitizes and validates the request body and stores the result in to the value pointed to by form.

func (*Handler) Encode

func (h *Handler) Encode(w http.ResponseWriter, req *http.Request, view Viewable, code int) error

Encode encodes the view and responds to the request.

func (*Handler) Export

func (h *Handler) Export(exporter Exporter) error

Export walks the named routes and applies the exporter to the response body. A nil exporter writes to the dist directory within the current working directory. See FileSystemExporter documentation for more details.

func (*Handler) FileServer

func (h *Handler) FileServer(pattern string, fs fs.FS, opts ...RouteOption) *Route

FileServer registers a fs.FS as a file server.

The pattern is expected to be a prefix wildcard route. The pattern prefix is removed from the request URL before handled.

If fs is an implementation of CacheControlFS, the files will be served with the associated Cache-Control policy.

Wrap the fs with AssetCacheFS to apply an aggressive caching policy, suitable for asset file names that contain a hash of their contents.

func (*Handler) Handle

func (h *Handler) Handle(pattern string, handler http.Handler, opts ...RouteOption) *Route

Handle registers a standard net/http Handler.

func (*Handler) Redirect

func (h *Handler) Redirect(url string, code int) error

Redirect replies to the request with a redirect.

func (*Handler) RedirectTo

func (h *Handler) RedirectTo(name string, params Params, query url.Values, code int) error

RedirectTo replies to the request with a redirect to a named route.

func (*Handler) ServeHTTP

func (h *Handler) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP initializes a new request context and dispatches to the matching route by calling it's prepared handler.

ServeHTTP implements the http.Handler interface.

func (*Handler) Use

func (h *Handler) Use(middleware ...func(http.Handler) http.Handler)

Use appends middleware to the global middleware stack.

func (*Handler) Walk

func (h *Handler) Walk(fn WalkFunc) error

Walk walks the named routes if the Router is a Walker.

type HandlerFunc

type HandlerFunc func(w http.ResponseWriter, req *http.Request) error

HandlerFunc represents a HTTP handler with error handling.

type HealthCheck

type HealthCheck []HealthChecker

HealthCheck is a basic healthcheck handler.

The handler will respond with a plain text HTTP 200 OK if and only if all checks return non-nil. If any check fails, the handler will respond with a HTTP 500 Internal Server Error.

func (HealthCheck) ServeHTTP

func (h HealthCheck) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface.

type HealthChecker

type HealthChecker interface {
	// Check checks the status of a resource.
	// Return a non-nil error to fail the healthcheck.
	Check() error
}

HealthChecker represents the ability to check the health of a resource.

type HealthCheckerFunc

type HealthCheckerFunc func() error

HealthCheckFunc is an adapter to allow the use of ordinary functions as HealthChecks.

func (HealthCheckerFunc) Check

func (fn HealthCheckerFunc) Check() error

Check implements the HealthChecker interface.

type Logger

type Logger func(req *http.Request, err error)

Logger represents the ability to log errors.

type Observer

type Observer interface {
	// Abort is called after an error is resolved to a view.
	Abort(req *http.Request)

	// Begin is called immediately after the request context is
	// initialized and before the route is dispatched.
	Begin(req *http.Request)

	// Commit is called at the end of the request. The start time of
	// the request is passed for the ability to observe latency.
	Commit(req *http.Request, t time.Time)
}

Observer represents the ability to observe a request.

type Option

type Option func(*Handler)

Option represents a functional option for configuration.

func WithDecoder

func WithDecoder(fn DecoderFunc) Option

WithDecoder sets the decoder negotiation function.

func WithEncoder

func WithEncoder(fn EncoderFunc) Option

WithEncoder sets the encoder negotiation function.

func WithLocales

func WithLocales(tags []language.Tag) Option

WithLocales sets the supported language tags.

func WithLogger

func WithLogger(logger Logger) Option

WithLogger sets the logger.

func WithObserver

func WithObserver(observer Observer) Option

WithObserver sets the observer.

func WithPool

func WithPool(pool Pool) Option

WithPool sets the buffer pool for encoding responses.

func WithResolver

func WithResolver(resolver Resolver) Option

WithResolver sets the error resolver.

func WithRouter

func WithRouter(router Router) Option

WithRouter sets the request router.

type Panic

type Panic struct {
	// contains filtered or unexported fields
}

Panic is an error resolved from a panic with a stack trace.

func (Panic) Error

func (e Panic) Error() string

Error implements the error interface.

func (Panic) String

func (e Panic) String() string

String implements the fmt.Stringer interface.

type Params

type Params map[string]string

Params represents the route parameters.

type Pool

type Pool interface {
	Get() *bytes.Buffer
	Put(b *bytes.Buffer)
}

Pool represents a buffer pool.

type Resolver

type Resolver interface {
	Resolve(req *http.Request, code int, err error) Error
}

Resolver represents the ability to resolve an error to a view.

type ResolverFunc

type ResolverFunc func(req *http.Request, code int, err error) Error

ResolverFunc is an adapter to allow the use of ordinary functions as Resolvers.

func (ResolverFunc) Resolve

func (fn ResolverFunc) Resolve(req *http.Request, code int, err error) Error

Resolve implements the Resolver interface.

type Route

type Route struct {
	// contains filtered or unexported fields
}

Route represents a route.

func Match

func Match(req *http.Request) *Route

Match returns the matching route for the request, or nil if no match.

func NewRoute

func NewRoute(pattern string, handler http.Handler, opts ...RouteOption) *Route

NewRoute returns a new route.

func (*Route) Methods

func (r *Route) Methods() []string

Methods returns the methods the route responds to.

func (*Route) Name

func (r *Route) Name() string

Name returns the route name.

func (*Route) Pattern

func (r *Route) Pattern() string

Pattern returns the route pattern.

func (*Route) ServeHTTP

func (r *Route) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface.

type RouteOption

type RouteOption func(*Route)

RouteOption represents a functional option for configuration.

func WithMethod

func WithMethod(method ...string) RouteOption

WithMethod sets the methods for which the route is valid.

func WithMiddleware

func WithMiddleware(middleware ...func(http.Handler) http.Handler) RouteOption

WithMiddleware appends middleware to the middleware stack.

func WithName

func WithName(name string) RouteOption

WithName sets the route name.

type Router

type Router interface {
	Add(r *Route) error
	Match(req *http.Request) (*Route, Params, error)
}

Router represents the ability to match HTTP requests to handlers.

type ValidationError

type ValidationError struct {
	// contains filtered or unexported fields
}

ValidationError represents a form validation error.

func (ValidationError) Error

func (e ValidationError) Error() string

Error implements the error interface.

func (ValidationError) Unwrap

func (e ValidationError) Unwrap() error

Unwrap returns the underlying error.

type Viewable

type Viewable interface{}

Viewable represents a view. To provide an expressive API, this type is an alias for interface{} that is named for documentation.

type WalkFunc

type WalkFunc func(r *Route) error

WalkFunc is called for each route visited. Return a non-nil error to terminate iteration.

type Walker

type Walker interface {
	Walk(fn WalkFunc) error
}

Walker represents the ability to walk the available routes.

Jump to

Keyboard shortcuts

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