rex

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Oct 29, 2024 License: MIT Imports: 31 Imported by: 0

README

rex

logo

rex is a minimalistic but robust HTTP router built on Go 1.22’s enhanced http.ServeMux. It offers a range of features for rapid web application development, including:

  • Middleware Support: Apply middleware globally or to specific routes and groups.
  • Helper Methods: Simplify defining routes and working with request/response handlers.
  • Template Rendering: Includes automatic template inheritance (e.g., using a base template), passing context data to templates, an error template that displays error messages, and more.
  • Body Parsing: Supports decoding multiple content types:
    • JSON
    • XML
    • URL-encoded and multipart forms
      Works with standard Go types, pointers, slices, and custom types implementing the rex.FormScanner interface.
  • Validation: Validate request data using the validator package.
  • SPA Support:
    Use r.SPA to serve a single-page application.
  • Route Grouping and Subgroups:
    Apply middleware to groups or individual routes for better organization.
  • Built-in Middleware:
    • Logging: Uses Go’s slog package.
    • Panic Recovery: Gracefully handles panics.
    • ETag Support: For caching optimization.
    • CORS Handling: Cross-Origin Resource Sharing middleware.
    • Seesion based cookie auth, Basic Auth & JWT Middleware: Secure your routes with seesion, basic or token-based authentication.
    • CSRF Protection: Protect your routes from CSRF attacks with the CSRF middleware.
  • Custom Middleware:
    Implement your own middleware by wrapping rex.Handler.
  • Static File Serving:
    Use r.Static to serve static files from a directory or r.StaticFS to serve files from a http.FileSystem.

    Both of these method can serve the minified version of the files if present and rex.ServeMinifiedAssetsIfPresent is set to true. You can also easily convert standard HTTP handlers to rex handlers:

  • Use rex.WrapHandler to wrap a http.Handler.
  • Use rex.WrapFunc to wrap a http.HandlerFunc.
  • Centralize error handling and logging by overriding the routers error handler. The default error handler handles rex.FormError from r.BodyParser and validator.ValidationErrors if there is a validation error.

Installation

go get -u github.com/abiiranathan/rex

Example: Custom Type Implementing FormScanner

This example shows how to implement a custom type that satisfies the FormScanner interface.

type Date time.Time // Date in format YYYY-MM-DD

// FormScan implements the FormScanner interface.
func (d *Date) FormScan(value interface{}) error {
	v, ok := value.(string)
	if !ok {
		return fmt.Errorf("date value is not a string")
	}

	t, err := time.Parse("2006-01-02", v)
	if err != nil {
		return fmt.Errorf("invalid date format")
	}
	*d = Date(t)
	return nil
}

Rendering Templates

For a complete example of template rendering and router usage, see the example in cmd/server/main.go.


Middleware

rex includes a few external libraries, used only in the middleware subpackage. Explore the middleware package for more details and usage examples.


Tests

Run all tests with the following command:

go test -v ./...

Benchmarks

Run benchmarks with memory profiling enabled:

go test -bench=. ./... -benchmem

Contributing

Pull requests are welcome! For major changes, please open an issue to discuss your ideas first.
Don’t forget to update tests as needed.


License

This project is licensed under the MIT License.

Documentation

Overview

Package rex (go router) implements a minimalistic but robust http router based on the standard go 1.22 enhanced routing capabilities in the `http.ServeMux`.

It adds features like middleware support, helper methods for defining routes, template rendering with automatic template inheritance (of a base template).

It also has a BodyParser that decodes json, xml, url-encoded and multipart forms based on content type. Form parsing supports all standard go types(and their pointers) and slices of standard types. It also supports custom types that implement the `rex.FormScanner` interface.

rex supports single page application routing with a dedicated method `r.SPAHandler` that serves the index.html file for all routes that do not match a file or directory in the root directory of the SPA.

The router also supports route groups and subgroups with middleware that can be applied to the entire group or individual routes. It has customizable built-in middleware for logging using the slog package, panic recovery, etag, cors, basic auth and jwt middlewares.

More middlewares can be added by implementing the Middleware type, a standard function that wraps rex.Handler.

Index

Constants

View Source
const (
	ContentTypeJSON          string = "application/json"
	ContentTypeXML           string = "application/xml"
	ContentTypeUrlEncoded    string = "application/x-www-form-urlencoded"
	ContentTypeMultipartForm string = "multipart/form-data"
	ContentTypeHTML          string = "text/html"
	ContentTypeCSV           string = "text/csv"
	ContentTypeText          string = "text/plain"
	ContentTypeEventStream   string = "text/event-stream"
)

Variables

View Source
var (
	// StrictHome when set to true, only the root path will be matched
	StrictHome = true

	// NoTrailingSlash when set to true, trailing slashes will be removed
	NoTrailingSlash = true

	// Serve minified files if present instead of original file.
	// This applies to StaticFS, Static functions.
	ServeMinified = false

	// MinExtensions is the slice of file extensions for which minified files are served.
	MinExtensions = []string{".js", ".css"}
)
View Source
var DefaultTimezone = time.UTC

Functions

func CreateFileSystem

func CreateFileSystem(frontendFS fs.FS, root string) http.FileSystem

Creates a new http.FileSystem from the fs.FS (e.g embed.FS) with the root directory. This is useful for serving single page applications.

func HandleFormErrors

func HandleFormErrors(c *Context, err FormError)

func HandleValidationErrors

func HandleValidationErrors(c *Context, errs validator.ValidationErrors)

func IsSafeMethod

func IsSafeMethod(method string) bool

Helper to check if the HTTP method is "safe" (no side effects).

func KebabCase

func KebabCase(s string) string

KebabCase converts a string to kebab-case. For more complex cases, use a third-party package like github.com/iancoleman/strcase.

func LoadTLSConfig

func LoadTLSConfig(certFile, keyFile string) (*tls.Config, error)

Open the certificate and key files and return a tls.Config

func Must

func Must[T any](value T, err error) T

Must unwraps the value and panics if the error is not nil.

func ParseTemplates

func ParseTemplates(rootDir string, funcMap template.FuncMap, suffix ...string) (*template.Template, error)

ParseTemplates recursively parses all the templates in the given directory and returns a template. The funcMap is applied to all the templates. The suffix is used to filter the files. The default suffix is ".html". If you have a file system, you can use ParseTemplatesFS instead.

func ParseTemplatesFS

func ParseTemplatesFS(root fs.FS, rootDir string, funcMap template.FuncMap, suffix ...string) (*template.Template, error)

ParseTemplatesFS parses all templates in a directory recursively from a given filesystem. It uses the specified `funcMap` to define custom template functions. The `suffix` argument can be used to specify a different file extension for the templates. The default file extension is ".html".

Example:

	t, err := rex.ParseTemplatesFS(
 	http.FS(http.Dir("templates")), "templates", template.FuncMap{
					"now": func() time.Time { return time.Now() },
		}, ".tmpl")

	 if err != nil {
	   log.Fatal(err)
	 }

	 r := rex.NewRouter(rex.WithTemplates(t))

func ParseTime

func ParseTime(v string, timezone *time.Location) (time.Time, error)

Parse time from string using specified timezone. If timezone is nil, UTC is used. Supported time formats are tried in order.

timeFormats := []string{
	time.RFC3339,                    // "2006-01-02T15:04:05Z07:00" (default go time)
	"2006-01-02T15:04:05.000Z07:00", // RFC 3339 format with milliseconds and a UTC timezone offset(JSON)
	"2006-01-02T15:04",              // HTML datetime-local format without seconds
	"2006-01-02T15:04:05",           // "2006-01-02T15:04:05"
	time.DateTime,                   // Custom format for "YYYY-MM-DD HH:MM:SS"
	time.DateOnly,                   // "2006-01-02" (html date format)
	time.TimeOnly,                   // "HH:MM:SS" (html time format)
}

func ParseTimeFormat

func ParseTimeFormat(value string, layout string, timezone ...string) (time.Time, error)

ParseTimeFormat parses a time string using the specified format and timezone. If timezone is not provided, UTC is used.

func SnakeCase

func SnakeCase(s string) string

SnakeCase converts a string to snake_case. For more complex cases, use a third-party package like github.com/iancoleman/strcase.

Types

type Context

type Context struct {
	Request  *http.Request
	Response *ResponseWriter
	// contains filtered or unexported fields
}

Context represents the context of the current HTTP request

func (*Context) AcceptHeader

func (c *Context) AcceptHeader() string

Accepts returns the best match from the Accept header.

func (*Context) BodyParser

func (c *Context) BodyParser(v interface{}, loc ...*time.Location) error

BodyParser parses the request body and stores the result in v. v must be a pointer to a struct. If timezone is provided, all date and time fields in forms are parsed with the provided location info. Otherwise rex.DefaultTimezone is used and defaults to UTC.

Supported content types: application/json, application/x-www-form-urlencoded, multipart/form-data, application/xml If you need to parse a different content type, you can implement a custom parser or use a third-party package like https://github.com/gorilla/schema package. Any form value can implement the FormScanner interface to implement custom form scanning. Struct tags are used to specify the form field name. If parsing forms, the default tag name is "form", followed by the "json" tag name, and then snake case of the field name.

func (*Context) ContentType

func (c *Context) ContentType() string

Returns the header content type stripping everything after ; like charset or form boundary in multipart/form-data forms.

func (*Context) Error

func (c *Context) Error(err error, status int, contentType ...string) error

Error sends an error response as plain text. You can optionally pass a content type. Status code is expected to be between 400 and 599.

func (*Context) ExecuteTemplate

func (c *Context) ExecuteTemplate(name string, data Map) error

Execute a standalone template without a layout.

func (*Context) FormFile

func (c *Context) FormFile(key string) (multipart.File, *multipart.FileHeader, error)

func (*Context) FormFiles

func (c *Context) FormFiles(key string, maxMemory ...int64) ([]*multipart.FileHeader, error)

func (*Context) FormValue

func (c *Context) FormValue(key string) string

Returns the form value by key.

func (*Context) FormValueInt added in v0.2.2

func (c *Context) FormValueInt(key string, defaults ...int) int

Returns the form value by key as an integer. If the value is not found or cannot be converted to an integer, it returns the default value.

func (*Context) FormValueUInt added in v0.2.2

func (c *Context) FormValueUInt(key string, defaults ...uint) uint

Returns the form value by key as an unsigned integer. If the value is not found or cannot be converted to an unsigned integer, it returns the default value.

func (*Context) Get

func (c *Context) Get(key interface{}) (value interface{}, exists bool)

Get retrieves a value from the context

func (*Context) GetHeader

func (c *Context) GetHeader(key string) string

GetHeader returns the status code of the response

func (*Context) GetOrEmpty added in v0.2.2

func (c *Context) GetOrEmpty(key interface{}) any

GetOrEmpty retrieves a value from the context or returns nil if the key does not exist. This better when you want to type-cast the value to a specific type without checking for existence.

func (*Context) HTML

func (c *Context) HTML(html string) error

Send HTML response.

func (*Context) Host added in v0.2.2

func (c *Context) Host() string

Host returns the request host.

func (*Context) IP

func (c *Context) IP() (string, error)

IP returns the client's IP address. It tries to get the IP from the X-Forwarded-For header first, then falls back to the X-Real-Ip header. If both headers are not set, it returns the remote address from the request.

func (*Context) JSON

func (c *Context) JSON(data interface{}) error

Context helper methods JSON sends a JSON response

func (*Context) Locals

func (c *Context) Locals() map[any]any

Locals returns the context values

func (*Context) LookupTemplate

func (c *Context) LookupTemplate(name string) (*template.Template, error)

LookupTemplate returns the template with the given name.

func (*Context) Method added in v0.2.2

func (c *Context) Method() string

Method returns the request method.

func (*Context) MustGet added in v0.2.1

func (c *Context) MustGet(key interface{}) interface{}

MustGet retrieves a value from the context or panics if the key does not exist.

func (*Context) Param

func (c *Context) Param(name string) string

Param gets a path parameter value by name from the request. If the parameter is not found, it checks the redirect options.

func (*Context) ParamInt

func (c *Context) ParamInt(key string, defaults ...int) int

paramInt returns the value of the parameter as an integer If the parameter is not found, it checks the redirect options.

func (*Context) ParamUInt added in v0.2.2

func (c *Context) ParamUInt(key string, defaults ...uint) uint

paramUInt returns the value of the parameter as an unsigned integer If the parameter is not found, it checks the redirect options.

func (*Context) Path added in v0.2.2

func (c *Context) Path() string

Path returns the request path.

func (*Context) Query

func (c *Context) Query(key string, defaults ...string) string

Query returns the value of the query as a string. If the query is not found, it checks the redirect options.

func (*Context) QueryInt

func (c *Context) QueryInt(key string, defaults ...int) int

queryInt returns the value of the query as an integer If the query is not found, it checks the redirect options.

func (*Context) QueryParser

func (c *Context) QueryParser(v interface{}, tag ...string) error

QueryParser parses the query string and stores the result in v.

func (*Context) QueryUInt added in v0.2.2

func (c *Context) QueryUInt(key string, defaults ...uint) uint

QueryUInt returns the value of the query as an unsigned integer If the query is not found, it checks the redirect options.

func (*Context) Redirect

func (c *Context) Redirect(url string, status ...int) error

Redirects the request to the given url. Default status code is 303 (http.StatusSeeOther)

func (*Context) RedirectRoute

func (c *Context) RedirectRoute(pathname string, options ...RedirectOptions) error

RedirectRoute redirects the request to the given route. The pathname is the name of the route to redirect to. The options are the redirect options like status code, query parameters etc.

func (*Context) Render

func (c *Context) Render(name string, data Map) error

Render the template tmpl with the data. If no template is configured, Render will panic. data is a map such that it can be extended with the request context keys if passContextToViews is set to true. If a file extension is missing, it will be appended as ".html".

func (*Context) RenderError

func (c *Context) RenderError(w http.ResponseWriter, err error, status ...int) error

RenderError renders the error template with the given error and status code.

func (*Context) Router

func (c *Context) Router() *Router

Returns the *rex.Router instance.

func (*Context) SaveFile

func (c *Context) SaveFile(fh *multipart.FileHeader, target string) error

save file from multipart form to disk

func (*Context) Send

func (c *Context) Send(data []byte) error

Send sends a raw response and returns an error. This conveniently returns only the error from the response writer.

func (*Context) Set

func (c *Context) Set(key interface{}, value interface{})

Set stores a value in the context

func (*Context) SetHeader

func (c *Context) SetHeader(key, value string)

SetHeader sets a header in the response

func (*Context) SetStatus

func (c *Context) SetStatus(status int) error

SetStatus sets the status code of the response

func (*Context) String

func (c *Context) String(format string, values ...interface{}) error

String sends a string response

func (*Context) Template

func (c *Context) Template() (*template.Template, error)

Template returns the template passed to the router.

func (*Context) TranslateErrors

func (c *Context) TranslateErrors(errs validator.ValidationErrors) map[string]string

Returns English translated errors for validation errors in map[string]string.

func (*Context) URL added in v0.2.2

func (c *Context) URL() string

URL returns the request URL.

func (*Context) Write

func (c *Context) Write(data []byte) (int, error)

Write sends a raw response

func (*Context) WriteHeader

func (c *Context) WriteHeader(status int) error

func (*Context) XML

func (c *Context) XML(data interface{}) error

XML sends an XML response

type FormError

type FormError struct {
	// The original error encountered.
	Err error `json:"err,omitempty"`

	// The kind of error encountered.
	Kind FormErrorKind `json:"kind,omitempty"`

	// Struct field name causing error.
	Field string `json:"field,omitempty"`
}

FormError represents an error encountered during body parsing.

func (FormError) Error

func (e FormError) Error() string

Error implements the error interface.

func (FormError) MarshalJSON

func (e FormError) MarshalJSON() ([]byte, error)

MarshalJSON marshals the error to JSON.

type FormErrorKind

type FormErrorKind string

FormErrorKind represents the kind of error encountered during body parsing.

const (
	// InvalidContentType indicates an unsupported content type.
	InvalidContentType FormErrorKind = "invalid_content_type"

	// InvalidStructPointer indicates that the provided v is not a pointer to a struct.
	InvalidStructPointer FormErrorKind = "invalid_struct_pointer"

	// RequiredFieldMissing indicates that a required field was not found.
	RequiredFieldMissing FormErrorKind = "required_field_missing"

	// UnsupportedType indicates that an unsupported type was encountered.
	UnsupportedType FormErrorKind = "unsupported_type"

	// ParseError indicates that an error occurred during parsing.
	ParseError FormErrorKind = "parse_error"
)

type FormScanner

type FormScanner interface {
	// FormScan scans the form value and stores the result in the receiver.
	FormScan(value interface{}) error
}

FormScanner is an interface for types that can scan form values. It is used to implement custom form scanning for types that are not supported by default.

type Group

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

Group is a collection of routes with a common prefix.

func (*Group) DELETE added in v0.2.0

func (g *Group) DELETE(path string, handler HandlerFunc, middlewares ...Middleware)

DELETE request.

func (*Group) GET added in v0.2.0

func (g *Group) GET(path string, handler HandlerFunc, middlewares ...Middleware)

GET request.

func (*Group) Group

func (g *Group) Group(prefix string, middlewares ...Middleware) *Group

Creates a nested group with the given prefix and middleware.

func (*Group) PATCH added in v0.2.0

func (g *Group) PATCH(path string, handler HandlerFunc, middlewares ...Middleware)

PATCH request.

func (*Group) POST added in v0.2.0

func (g *Group) POST(path string, handler HandlerFunc, middlewares ...Middleware)

POST request.

func (*Group) PUT added in v0.2.0

func (g *Group) PUT(path string, handler HandlerFunc, middlewares ...Middleware)

PUT request.

func (*Group) Static

func (g *Group) Static(prefix, dir string, maxAge ...int)

Static serves files from the given file system root.

func (*Group) StaticFs

func (g *Group) StaticFs(prefix string, fs http.FileSystem, maxAge ...int)

StaticFs serves files from the given file system.

func (*Group) Use

func (g *Group) Use(middlewares ...Middleware)

Use adds middlewares to the group.

type HandlerFunc

type HandlerFunc func(c *Context) error

HandlerFunc is the signature for route handlers that can return errors

func WrapFunc

func WrapFunc(h http.HandlerFunc) HandlerFunc

Convert http.HandlerFunc to HandlerFunc

func WrapHandler

func WrapHandler(h http.Handler) HandlerFunc

Convert http.Handler to HandlerFunc

func (HandlerFunc) ServeHTTP

func (h HandlerFunc) ServeHTTP(w http.ResponseWriter, r *http.Request)

Convert HandlerFunc to http.Handler. Note that this will not work with middlewares as the context is not passed to the handler and the router is not set(i.e c.router is nil).

type Map

type Map map[string]any

Generic type for response data

type Middleware

type Middleware func(HandlerFunc) HandlerFunc

Middleware function that takes a HandlerFunc and returns a HandlerFunc

func WrapMiddleware added in v0.2.1

func WrapMiddleware(middleware func(http.Handler) http.Handler) Middleware

WrapMiddleware wraps an http middleware to be used as a rex middleware.

type RedirectOptions

type RedirectOptions struct {
	Status      int               // status code to use for the redirect
	Params      map[string]string // query parameters to add to the redirect URL
	QueryParams map[string]string // query parameters to add to the redirect URL
}

type ResponseWriter

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

ResponseWriter wraps http.ResponseWriter with additional functionality

func (*ResponseWriter) Flush

func (w *ResponseWriter) Flush()

Implements the http.Flusher interface to allow an HTTP handler to flush buffered data to the client. This is useful for chunked responses and server-sent events.

func (*ResponseWriter) Header

func (rw *ResponseWriter) Header() http.Header

ResponseWriter interface

func (*ResponseWriter) Hijack

func (w *ResponseWriter) Hijack() (net.Conn, *bufio.ReadWriter, error)

Hijack lets the caller take over the connection.

func (*ResponseWriter) ReadFrom

func (w *ResponseWriter) ReadFrom(r io.Reader) (n int64, err error)

ReadFrom reads data from an io.Reader and writes it to the connection. All data is written in a single call to Write, so the data should be buffered. The return value is the number of bytes written and an error, if any.

func (*ResponseWriter) Size

func (w *ResponseWriter) Size() int

func (*ResponseWriter) Status

func (w *ResponseWriter) Status() int

func (*ResponseWriter) Unwrap

func (w *ResponseWriter) Unwrap() http.ResponseWriter

Satisfy http.ResponseController support (Go 1.20+) More about ResponseController: https://go.dev/ref/spec#ResponseController

func (*ResponseWriter) Write

func (w *ResponseWriter) Write(b []byte) (int, error)

Write writes the data to the connection as part of an HTTP reply. Satisfies the io.Writer interface. Calling this with a HEAD request will only write the headers if they haven't been written yet.

func (*ResponseWriter) WriteHeader

func (w *ResponseWriter) WriteHeader(status int)

WriteHeader writes the status code to the response. Calling the method more than once will have no effect.

type RouteInfo

type RouteInfo struct {
	Method  string `json:"method,omitempty"` // Http method.
	Path    string `json:"path,omitempty"`   // Registered pattern.
	Handler string `json:"-"`                // Function name for the handler.
}

RouteInfo contains information about a registered route.

type Router

type Router struct {

	// Handler for 404 not found errors. Note that when this is called,
	// The request parameters are not available, since they are populated by the http.ServeMux
	// when the request is matched to a route. So calling r.PathValue() will return "".
	NotFoundHandler http.Handler
	// contains filtered or unexported fields
}

Router is the main router structure

func NewRouter

func NewRouter(options ...RouterOption) *Router

NewRouter creates a new router with the given options. The router wraps the http.DefaultServeMux and adds routing and middleware capabilities. The router uses slog for logging. The default log level is Error with JSON formatting. The router also performs automatic body parsing and struct validation with the go-playground/validator/v10 package.

func (*Router) CONNECT

func (r *Router) CONNECT(pattern string, handler HandlerFunc, middlewares ...Middleware)

CONNECT http request.

func (*Router) DELETE

func (r *Router) DELETE(pattern string, handler HandlerFunc, middlewares ...Middleware)

func (*Router) FaviconFS

func (r *Router) FaviconFS(fs http.FileSystem, path string)

Serve favicon.ico from the file system fs at path.

func (*Router) File

func (r *Router) File(path, file string)

Wrapper around http.ServeFile but applies global middleware to the handler.

func (*Router) FileFS

func (r *Router) FileFS(fs http.FileSystem, prefix, path string)

func (*Router) GET

func (r *Router) GET(pattern string, handler HandlerFunc, middlewares ...Middleware)

Common HTTP method handlers

func (*Router) Group

func (r *Router) Group(prefix string, middlewares ...Middleware) *Group

Group creates a new group with the given prefix and options.

func (*Router) HEAD

func (r *Router) HEAD(pattern string, handler HandlerFunc, middlewares ...Middleware)

HEAD request.

func (*Router) Handle

func (r *Router) Handle(method, pattern string, handler HandlerFunc, middlewares ...Middleware)

Handle registers a new route with the given path and handler

func (*Router) OPTIONS

func (r *Router) OPTIONS(pattern string, handler HandlerFunc, middlewares ...Middleware)

OPTIONS. This may not be necessary as registering GET request automatically registers OPTIONS.

func (*Router) PATCH

func (r *Router) PATCH(pattern string, handler HandlerFunc, middlewares ...Middleware)

func (*Router) POST

func (r *Router) POST(pattern string, handler HandlerFunc, middlewares ...Middleware)

func (*Router) PUT

func (r *Router) PUT(pattern string, handler HandlerFunc, middlewares ...Middleware)

func (*Router) RegisterValidation

func (r *Router) RegisterValidation(tag string, fn validator.Func)

RegisterValidation adds a validation with the given tag

NOTES: - if the key already exists, the previous validation function will be replaced. - this method is not thread-safe it is intended that these all be registered prior to any validation

func (*Router) RegisterValidationCtx

func (r *Router) RegisterValidationCtx(tag string, fn validator.FuncCtx)

RegisterValidationCtx does the same as RegisterValidation on accepts a FuncCtx validation allowing context.Context validation support.

func (*Router) RegisteredRoutes

func (r *Router) RegisteredRoutes() []RouteInfo

RegisteredRoutes returns a list of registered routes in a slice of RouteInfo.

func (*Router) SPA

func (r *Router) SPA(pattern string, index string, frontend http.FileSystem, options ...SPAOption)

SPA serves a single page application (SPA) with the given index file. The index file is served for all routes that do not match a static file except for routes that are skipped by the skipFunc or have an extension.

The frontend is served from the given http.FileSystem. You can use the CreateFileSystem function to create a new http.FileSystem from a fs.FS (e.g embed.FS). To customize the cache control and skip behavior, you can use the WithCacheControl and WithSkipFunc options.

func (*Router) ServeHTTP

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

ServeHTTP implements the http.Handler interface

func (*Router) SetErrorHandler

func (r *Router) SetErrorHandler(handler func(*Context, error))

Set error handler for centralized error handling

func (*Router) Static

func (r *Router) Static(prefix, dir string, maxAge ...int)

Serve static assests at prefix in the directory dir. e.g r.Static("/static", "static"). This method will strip the prefix from the URL path. To serve minified assets(JS and CSS) if present, call rex.ServeMinifiedAssetsIfPresent=true. To enable caching, provide maxAge seconds for cache duration.

func (*Router) StaticFS

func (r *Router) StaticFS(prefix string, fs http.FileSystem, maxAge ...int)

Like Static but for http.FileSystem. Use this to serve embedded assets with go/embed.

mux.StaticFS("/static", http.FS(staticFs))

To enable caching, provide maxAge seconds for cache duration.

func (*Router) TRACE

func (r *Router) TRACE(pattern string, handler HandlerFunc, middlewares ...Middleware)

TRACE http request.

func (*Router) Use

func (r *Router) Use(middlewares ...Middleware)

Global middleware

type RouterOption

type RouterOption func(*Router)

Router option a function option for configuring the router.

func BaseLayout

func BaseLayout(baseLayout string) RouterOption

BaseLayout sets the base layout template for the router. If set, this template will be used as the base layout for all views. The `contentBlock` variable will be replaced with the rendered content of the view.

Example:

r := rex.NewRouter(rex.BaseLayout("layouts/base.html"))

func ContentBlock

func ContentBlock(contentBlock string) RouterOption

ContentBlock sets the name of the content block in the base layout template. This block will be replaced with the rendered content of the view. The default content block name is "content".

Example:

r := rex.NewRouter(rex.ContentBlock("main"))

func ErrorTemplate

func ErrorTemplate(errorTemplate string) RouterOption

ErrorTemplate sets the error template for the router. If set, this template will be used to render errors. It is passed "error", "status", "status_text" in its context.

func PassContextToViews

func PassContextToViews(passContextToViews bool) RouterOption

PassContextToViews enables or disables passing the router context to views. If enabled, the router context will be available as a variable named "ctx" in the views. This allows views to access information about the request and the router. The default value is `false`.

Example:

r := rex.NewRouter(rex.PassContextToViews(true))

func WithLogger

func WithLogger(logger *slog.Logger) RouterOption

Replace the default slog.Logger with a custom logger.

func WithTemplates

func WithTemplates(t *template.Template) RouterOption

WithTemplates sets the template for the router. This template will be used to render views.

Example:

t := template.Must(template.ParseFiles("views/index.html"))
r := rex.NewRouter(rex.WithTemplates(t))

type SPAOption

type SPAOption func(*spaHandler)

SPAOptions for customizing the cache control and index file.

func WithCacheControl

func WithCacheControl(cacheControl string) SPAOption

WithCacheControl sets the Cache-Control header for the index file.

func WithResponseModifier

func WithResponseModifier(responseModifier http.HandlerFunc) SPAOption

WithResponseModifier sets a function to modify the response before serving the index file.

func WithSkipFunc

func WithSkipFunc(skipFunc func(r *http.Request) bool) SPAOption

WithSkipFunc sets a function to skip the SPA handler for certain requests.

type Server

type Server struct {
	*http.Server
}

Wrapper around the standard http.Server. Adds easy graceful shutdown, functional options for customizing the server, and HTTP/2 support.

func NewServer

func NewServer(addr string, handler http.Handler, options ...ServerOption) *Server

Create a new Server instance with HTTP/2 support.

func (*Server) Shutdown

func (s *Server) Shutdown(timeout ...time.Duration)

Gracefully shuts down the server. The default timeout is 5 seconds to wait for pending connections.

type ServerOption

type ServerOption func(*Server)

Option for configuring the server.

func WithHTTP2Options

func WithHTTP2Options(http2ServerOptions http2.Server) ServerOption

New option to fine-tune HTTP/2 settings

func WithIdleTimeout

func WithIdleTimeout(d time.Duration) ServerOption

func WithReadTimeout

func WithReadTimeout(d time.Duration) ServerOption

func WithTLSConfig

func WithTLSConfig(config *tls.Config) ServerOption

func WithWriteTimeout

func WithWriteTimeout(d time.Duration) ServerOption

Directories

Path Synopsis
cmd
middleware
auth
Package auth provides session-based authentication middleware for the Rex router.
Package auth provides session-based authentication middleware for the Rex router.
csrf
Description: CSRF protection middleware for Go web servers.
Description: CSRF protection middleware for Go web servers.

Jump to

Keyboard shortcuts

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