Documentation
¶
Overview ¶
Package rmhttp implements a lightweight wrapper around the standard library web server provided by http.Server and http.ServeMux, and adds an intuitive fluent interface for easy use and configuration of route grouping, logging, CORS, panic recovery, header management, timeouts, and middleware.
Index ¶
- func TimeoutMiddleware(timeout Timeout) func(http.Handler) http.Handler
- func ValidHTTPMethods() []string
- type App
- func (app *App) Compile()
- func (app *App) Delete(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Get(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Group(pattern string) *Group
- func (app *App) Handle(method string, pattern string, handler http.Handler) *Route
- func (app *App) HandleFunc(method string, pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) ListenAndServe() error
- func (app *App) ListenAndServeTLS(cert string, key string) error
- func (app *App) Options(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Patch(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Post(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Put(pattern string, handlerFunc http.HandlerFunc) *Route
- func (app *App) Redirect(pattern string, target string, code int) *Route
- func (app *App) Route(route *Route)
- func (app *App) Routes() map[string]*Route
- func (app *App) Shutdown(ctx context.Context) error
- func (app *App) Static(pattern string, targetDir string) *Route
- func (app *App) StatusMethodNotAllowedHandler(handler http.HandlerFunc)
- func (app *App) StatusNotFoundHandler(handler http.HandlerFunc)
- func (app *App) Use(middlewares ...func(http.Handler) http.Handler) *App
- func (app *App) WithHeader(key string, value string) *App
- func (app *App) WithMiddleware(middlewares ...func(http.Handler) http.Handler) *App
- func (app *App) WithTimeout(timeout time.Duration, message string) *App
- type CaptureWriter
- func (cw *CaptureWriter) Flush()
- func (cw *CaptureWriter) Header() http.Header
- func (cw *CaptureWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
- func (cw *CaptureWriter) Push(target string, opts *http.PushOptions) error
- func (cw *CaptureWriter) Unwrap() http.ResponseWriter
- func (cw *CaptureWriter) Write(body []byte) (int, error)
- func (cw *CaptureWriter) WriteHeader(code int)
- type Config
- type Group
- func (group *Group) ComputedRoutes() map[string]*Route
- func (group *Group) Delete(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Get(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Group(g *Group) *Group
- func (group *Group) Handle(method string, pattern string, handler http.Handler) *Group
- func (group *Group) HandleFunc(method string, pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Options(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Patch(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Post(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Put(pattern string, handlerFunc http.HandlerFunc) *Group
- func (group *Group) Route(route *Route) *Group
- func (group *Group) Use(middlewares ...func(http.Handler) http.Handler) *Group
- func (group *Group) WithHeader(key, value string) *Group
- func (group *Group) WithMiddleware(middlewares ...func(http.Handler) http.Handler) *Group
- func (group *Group) WithTimeout(timeout time.Duration, message string) *Group
- type HTTPError
- type Route
- func (route *Route) ComputedHeaders() map[string]string
- func (route *Route) ComputedMiddleware() []func(http.Handler) http.Handler
- func (route *Route) ComputedPattern() string
- func (route *Route) ComputedTimeout() Timeout
- func (route *Route) String() string
- func (route *Route) Use(middlewares ...func(http.Handler) http.Handler) *Route
- func (route *Route) WithHeader(key, value string) *Route
- func (route *Route) WithMiddleware(middlewares ...func(http.Handler) http.Handler) *Route
- func (route *Route) WithTimeout(timeout time.Duration, message string) *Route
- type Router
- type Server
- type ServerConfig
- type Timeout
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func TimeoutMiddleware ¶
TimeoutMiddleware creates, initialises and returns a middleware function that will wrap the next handler in the stack with a timeout handler.
func ValidHTTPMethods ¶
func ValidHTTPMethods() []string
ValidHTTPMethods returns a slice of strings containing all of the HTTP methods that rmhttp will accept.
Types ¶
type App ¶
App encapsulates the application and provides the public API, as well as orchestrating the core library functionality.
func New ¶
New creates, initialises and returns a pointer to a new App. An optional configuration can be passed to configure many parts of the system, such as cors, SSL, and timeouts.
If you chose not to pass in a configuration, rmhttp will first attempt to load configuration values from environment variables, and if they're not found, will apply sensible defaults.
func (*App) Compile ¶
func (app *App) Compile()
Compile prepares the app for starting by applying the middleware, and loading the Routes. It should be the last function to be called before starting the Server.
func (*App) Delete ¶
func (app *App) Delete( pattern string, handlerFunc http.HandlerFunc, ) *Route
Delete binds the passed handler to the specified route pattern for DELETE requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Get ¶
func (app *App) Get( pattern string, handlerFunc http.HandlerFunc, ) *Route
Get binds the passed handler to the specified route pattern for GET requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Group ¶
Group creates, initialises, and returns a pointer to a Route Group.
This is typically used to create new Routes as part of the Group, but can also be used to add Group specific middleware, timeouts, etc.
This method will return a pointer to the new Group, allowing the user to chain any of the other builder methods that Group implements.
func (*App) Handle ¶
Handle binds the passed http.Handler to the specified route method and pattern.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) HandleFunc ¶
HandleFunc binds the passed http.HandlerFunc to the specified route method and pattern.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) ListenAndServe ¶
ListenAndServe compiles and loads the registered Routes, and then starts the Server without SSL.
func (*App) ListenAndServeTLS ¶
ListenAndServeTLS compiles and loads the registered Routes, and then starts the Server with the SSL certificate and key at the file paths passed as the arguments.
func (*App) Options ¶
func (app *App) Options( pattern string, handlerFunc http.HandlerFunc, ) *Route
Options binds the passed handler to the specified route pattern for OPTIONS requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Patch ¶
func (app *App) Patch( pattern string, handlerFunc http.HandlerFunc, ) *Route
Patch binds the passed handler to the specified route pattern for PATCH requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Post ¶
func (app *App) Post( pattern string, handlerFunc http.HandlerFunc, ) *Route
Post binds the passed handler to the specified route pattern for POST requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Put ¶
func (app *App) Put( pattern string, handlerFunc http.HandlerFunc, ) *Route
Put binds the passed handler to the specified route pattern for PUT requests.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Redirect ¶
Redirect creates and binds a redirect handler to the specified pattern for GET requests.
A temporary redirect status code will be used if the passed code is not in the 300 - 308 range.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) Route ¶
Route adds a Route to the application at the top level.
This allows us to overwrite Routes prior to application start without causing the underlying http.ServeMux to throw an error.
func (*App) Static ¶
Static creates and binds a filesystem handler to the specified pattern for GET requests.
If the pattern contains a trailing slash, the filesystem handler may not behave as expected.
This method will return a pointer to the new Route, allowing the user to chain any of the other builder methods that Route implements.
func (*App) StatusMethodNotAllowedHandler ¶
func (app *App) StatusMethodNotAllowedHandler( handler http.HandlerFunc, )
StatusMethodNotAllowedHandler registers a handler to be used when an internal 405 error is thrown.
func (*App) StatusNotFoundHandler ¶
func (app *App) StatusNotFoundHandler(handler http.HandlerFunc)
StatusNotFoundHandler registers a handler to be used when an internal 404 error is thrown.
func (*App) Use ¶
Use is a convenience method for adding global middleware handlers. It uses WithMiddleware behind the scenes.
This method will return a pointer to the app, allowing the user to chain any of the other builder methods that the app implements.
func (*App) WithHeader ¶
WithHeader adds an HTTP header at the global level. Calling this method more than once with the same key will overwrite the existing header.
This method will return a pointer to the app, allowing the user to chain any of the other builder methods that the app implements.
func (*App) WithMiddleware ¶
WithMiddleware is a convenience method for adding global middleware handlers.
This method will return a pointer to the app, allowing the user to chain any of the other builder methods that the app implements.
func (*App) WithTimeout ¶
WithTimeout sets a request timeout amount and message at the global level.
This method will return a pointer to the app, allowing the user to chain any of the other builder methods that the app implements.
type CaptureWriter ¶
type CaptureWriter struct {
Writer http.ResponseWriter
Code int
Body string
Mu sync.Mutex
PassThrough bool
}
A CaptureWriter wraps a http.ResponseWriter in order to capture HTTP the response code & body that handlers will set. We do this to allow reading these values after they have been set, as this is not normally possible on a ResponseWriter.
func NewCaptureWriter ¶
func NewCaptureWriter(w http.ResponseWriter) *CaptureWriter
New creates, instantiates, and returns a new CaptureWriter.
func (*CaptureWriter) Flush ¶
func (cw *CaptureWriter) Flush()
Flush implements the Flusher interface.
func (*CaptureWriter) Header ¶
func (cw *CaptureWriter) Header() http.Header
Header implements part of the http.ResponseWriter interface. We simply pass this to the underlying ResponseWriter, as you can already retrieve a Header from that.
func (*CaptureWriter) Hijack ¶
func (cw *CaptureWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)
Hijack implements the Hijacker interface.
func (*CaptureWriter) Push ¶
func (cw *CaptureWriter) Push(target string, opts *http.PushOptions) error
Push implements the Pusher interface.
func (*CaptureWriter) Unwrap ¶
func (cw *CaptureWriter) Unwrap() http.ResponseWriter
Unwrap returns the underlying http.ResponseWriter. It is used internally by http.ResponseController, which allows you to use custom http.ResponseWriter instances more easily.
func (*CaptureWriter) Write ¶
func (cw *CaptureWriter) Write(body []byte) (int, error)
Write implements part of the http.ResponseWriter interface. We override it here in order to store the response body, before optionally writing to the underlying ResponseWriter.
func (*CaptureWriter) WriteHeader ¶
func (cw *CaptureWriter) WriteHeader(code int)
WriteHeader implements part of the http.ResponseWriter interface. We override it here in order to store the response code, before optionally writing to the underlying ResponseWriter.
type Config ¶
type Config struct {
Debug bool `env:"DEBUG"`
Server ServerConfig
}
The Config contains settings (with defaults) for configuring the app, server and router.
func LoadConfig ¶
loadConfig parses the environment variables defined in the Config objects (with defaults), then merges those with the config that the user may have supplied. This function only gets called during app initialisation.
This function will return a completed config, or error if the environment variables cannot be parsed.
type Group ¶
type Group struct {
Pattern string
Middleware []func(http.Handler) http.Handler
Timeout Timeout
Headers map[string]string
Parent *Group
Routes map[string]*Route
Groups map[string]*Group
}
A Group allows for grouping sub groups or routes under a route prefix. It also enables you to add headers, timeout and middleware once to every sub group and route included in the group.
func (*Group) ComputedRoutes ¶
ComputedRoutes returns a map of unique Routes composed from this Group and any sub Groups of this Group.
func (*Group) Delete ¶
func (group *Group) Delete( pattern string, handlerFunc http.HandlerFunc, ) *Group
Delete binds the passed handler to the specified route pattern for DELETE requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Get ¶
func (group *Group) Get( pattern string, handlerFunc http.HandlerFunc, ) *Group
Get binds the passed handler to the specified route pattern for GET requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Group ¶
Group adds the passed Group as a sub group to this Group.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Handle ¶
Handle binds the passed rmhttp.Handler to the specified route method and pattern.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) HandleFunc ¶
func (group *Group) HandleFunc( method string, pattern string, handlerFunc http.HandlerFunc, ) *Group
HandleFunc converts the passed handler function to a rmhttp.HandlerFunc, and then binds it to the specified route method and pattern.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Options ¶
func (group *Group) Options( pattern string, handlerFunc http.HandlerFunc, ) *Group
Options binds the passed handler to the specified route pattern for OPTIONS requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Patch ¶
func (group *Group) Patch( pattern string, handlerFunc http.HandlerFunc, ) *Group
Patch binds the passed handler to the specified route pattern for PATCH requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Post ¶
func (group *Group) Post( pattern string, handlerFunc http.HandlerFunc, ) *Group
Post binds the passed handler to the specified route pattern for POST requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Put ¶
func (group *Group) Put( pattern string, handlerFunc http.HandlerFunc, ) *Group
Put binds the passed handler to the specified route pattern for PUT requests.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Route ¶
Route adds the passed Route to this Group.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) Use ¶
Use is a convenience method for adding middleware handlers to a Group. It uses WithMiddleware behind the scenes.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) WithHeader ¶
WithHeader sets an HTTP header for this Group. Calling this method with the same key more than once will overwrite the existing header.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) WithMiddleware ¶
WithMiddleware adds Middleware handlers to the receiver Group.
Each middleware handler will be wrapped to create a call stack with the order in which the middleware is added being maintained. So, for example, if the user added A and B middleware via this method, the resulting callstack would be as follows -
Middleware A -> Middleware B -> Route Handler -> Middleware B -> Middleware A
(This actually a slight simplification, as internal middleware such as HTTP Logging, CORS, HTTP Error Handling and Route Panic Recovery may also be inserted into the call stack, depending on how the App is configured).
The middlewares argument is variadic, allowing the user to add multiple middleware functions in a single call.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
func (*Group) WithTimeout ¶
WithTimeout sets a request timeout amount and message for this Group.
This method will return a pointer to the receiver Group, allowing the user to chain any of the other builder methods that Group implements.
type HTTPError ¶
An HTTPError represents an error with an additional HTTP status code
func NewHTTPError ¶
NewHTTPError creates and returns a new, initialised pointer to a HTTPError
type Route ¶
type Route struct {
Method string
Pattern string
Handler http.Handler
Middleware []func(http.Handler) http.Handler
Timeout Timeout
Headers map[string]string
Parent *Group
}
A Route encapsulates all of the information that the router will need to satisfy an HTTP request. Alongside supplying standard information such as what HTTP method and URL pattern a handler should be bound to, the Route also allows the enclosed handler to be configured with their own timeout, headers, and middleware.
func NewRoute ¶
NewRoute validates the input, then creates, initialises and returns a pointer to a Route. The validation step ensures that a valid HTTP method has been passed (http.MethodGet will be used, if not). The method will also be transformed to uppercase, and the pattern to lowercase.
func (*Route) ComputedHeaders ¶
ComputedHeaders dynamically calculates the HTTP headers that have been added to the Route and any parent Groups.
func (*Route) ComputedMiddleware ¶
Middleware returns the slice of MiddlewareFuncs that have been added to the Route.
func (*Route) ComputedPattern ¶
ComputedPattern dynamically calculates the pattern for the Route. It returns the URL pattern as a string.
func (*Route) ComputedTimeout ¶
Timeout returns the Timeout object that has been added to the Route.
func (*Route) String ¶
String is used internally to calculate a string signature for use as map keys, etc.
func (*Route) Use ¶
Use is a convenience method for adding middleware handlers to a Route. It uses WithMiddleware behind the scenes.
This method will return a pointer to the receiver Route, allowing the user to chain any of the other builder methods that Route implements.
func (*Route) WithHeader ¶
WithHeader sets an HTTP header for this Route. Calling this method with the same key more than once will overwrite the existing header.
This method will return a pointer to the receiver Route, allowing the user to chain any of the other builder methods that Route implements.
func (*Route) WithMiddleware ¶
WithMiddleware adds Middleware handlers to the receiver Route.
Each middleware handler will be wrapped to create a call stack with the order in which the middleware is added being maintained. So, for example, if the user added A and B middleware via this method, the resulting callstack would be as follows -
Middleware A -> Middleware B -> Route Handler -> Middleware B -> Middleware A
(This actually a slight simplification, as internal middleware such as HTTP Logging, CORS, HTTP Error Handling and Route Panic Recovery may also be inserted into the call stack, depending on how the App is configured).
The middlewares argument is variadic, allowing the user to add multiple middleware functions in a single call.
This method will return a pointer to the receiver Route, allowing the user to chain any of the other builder methods that Route implements.
func (*Route) WithTimeout ¶
WithTimeout sets a request timeout amount and message for this route.
This method will return a pointer to the receiver Route, allowing the user to chain any of the other builder methods that Route implements.
type Router ¶
The Router loads Routes into the underlying HTTP request multiplexer, as well as handling each request, ensuring that ResponseWriter and Request objects are properly configured. The Router also manages custom error handlers to ensure that the HTTP Error Handler can operate properly.
func NewRouter ¶
func NewRouter() *Router
NewRouter intialises, creates, and then returns a pointer to a Router.
func (*Router) AddErrorHandler ¶
AddErrorHandler maps the passed response code and handler. These error handlers will be used instead of the http.Handler equivalents when available.
func (*Router) Handle ¶
Handle registers the passed Route with the underlying HTTP request multiplexer.
func (*Router) ServeHTTP ¶
func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP allows the Router to fulfill the http.Handler interface, meaning that we can use it as a handler for the underlying HTTP request multiplexer (which by default is a http.ServeMux).
We also intercept any error handlers returned by the underlying mux, and replace them with any custom error handlers that have been registered.
type Server ¶
type Server struct {
Server http.Server
Router http.Handler
Port int
Host string
// contains filtered or unexported fields
}
A Server wraps the standard library net/http.Server. It provide default lifecycle management and debugger logging on top of the expected http.Server behaviour.
func NewServer ¶
func NewServer( config ServerConfig, router http.Handler, ) *Server
NewServer creates, initialises and returns a pointer to a Server.
func (*Server) ListenAndServe ¶
ListenAndServe directly proxies the http.Server.ListenAndServe method. It starts the server without TLS support on the configured address and port.
func (*Server) ListenAndServeTLS ¶
ListenAndServeTLS directly proxies the http.Server.ListenAndServeTLS method. It starts the server with TLS support on the configured address and port.
type ServerConfig ¶
type ServerConfig struct {
TCPReadTimeout int `env:"TCP_READ_TIMEOUT" envDefault:"2"`
TCPReadHeaderTimeout int `env:"TCP_READ_HEADER_TIMEOUT" envDefault:"1"`
TCPIdleTimeout int `env:"TCP_IDLE_TIMEOUT" envDefault:"120"`
TCPWriteTimeout int `env:"TCP_WRITE_TIMEOUT" envDefault:"5"`
TCPWriteTimeoutPadding int `env:"TCP_WRITE_TIMEOUT_PADDING" envDefault:"1"`
RequestTimeout int `env:"HTTP_REQUEST_TIMEOUT" envDefault:"5"`
TimeoutMessage string `env:"HTTP_TIMEOUT_MESSAGE" envDefault:"Request Timeout"`
MaxHeaderBytes int `env:"HTTP_MAX_HEADER_BYTES"`
Host string `env:"HOST"`
Port int `env:"PORT" envDefault:"8080"`
DisableGeneralOptionsHandler bool
TLSConfig *tls.Config
TLSNextProto map[string]func(*http.Server, *tls.Conn, http.Handler)
ConnState func(net.Conn, http.ConnState)
ErrorLog *log.Logger
BaseContext func(net.Listener) context.Context
ConnContext func(ctx context.Context, c net.Conn) context.Context
HTTP2 *http.HTTP2Config
Protocols *http.Protocols
}
The ServerConfig contains settings (with defaults) for configuring the underlying http.Server, as well as some additional timeout related properties. The server properties correlate to those found at https://pkg.go.dev/net/http#Server.