rex

package module
v1.9.1 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 32 Imported by: 4

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

DefaultTimezone is the default timezone used when parsing form and query time values.

Functions

func CreateFileSystem

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

CreateFileSystem creates an http.FileSystem from fs rooted at root. This is useful for serving single page applications.

func First added in v1.6.1

func First[T any](elems []T, def T) T

First returns the first element in elems or def when elems is empty.

func IsSafeMethod

func IsSafeMethod(method string) bool

IsSafeMethod reports whether method is an HTTP safe method.

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)

LoadTLSConfig loads a certificate pair and returns a TLS configuration.

func Must

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

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

func ParseBool added in v0.3.8

func ParseBool(v string) bool

ParseBool reports whether v is one of the accepted true values. It treats "true", "1", and "on" as true, case-insensitively.

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)

ParseTime parses a time string using the provided timezone. If timezone is nil, DefaultTimezone is used. Supported time formats are tried in order.

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 SetError added in v1.0.1

func SetError(r *http.Request, err error)

SetError sets the error inside the request context that is retrieved and passed down the rex.Context. Useful for http handlers without access to rex.Context.

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       // Original Request object
	Response http.ResponseWriter // Wrapped Writer
	// contains filtered or unexported fields
}

Context represents the context of the current HTTP request

func NewContext added in v1.7.0

func NewContext(w http.ResponseWriter, r *http.Request, router *Router) *Context

NewContext creates a new Context instance for the given request and response. This is primarily useful for testing but can also be used when manually creating contexts outside of the normal routing flow.

func (*Context) AcceptHeader

func (c *Context) AcceptHeader() string

AcceptHeader returns the first media type from the Accept header.

func (*Context) BodyParser

func (c *Context) BodyParser(v any, 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

ContentType returns the request content type without parameters such as charset or multipart boundaries.

func (*Context) Deadline added in v1.7.0

func (c *Context) Deadline() (deadline time.Time, ok bool)

Deadline implements context.Context.

func (*Context) DelHeader added in v0.2.6

func (c *Context) DelHeader(key string)

DelHeader deletes a header in the response

func (*Context) Done added in v1.7.0

func (c *Context) Done() <-chan struct{}

Done implements context.Context.

func (*Context) Err added in v1.7.0

func (c *Context) Err() error

Err implements context.Context.

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

ExecuteTemplate executes a standalone template without a layout.

func (*Context) FormFile

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

FormFile returns the first uploaded file for key.

func (*Context) FormFiles

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

FormFiles returns all uploaded files for key after parsing the multipart form.

func (*Context) FormValue

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

FormValue returns the form value for key.

func (*Context) FormValueInt added in v0.2.2

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

FormValueInt returns the form value for 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

FormValueUInt returns the form value for 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 string) (value any, exists bool)

Get retrieves a value from the context

func (*Context) GetHeader

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

GetHeader returns the value of the request header

func (*Context) GetLogger added in v0.3.0

func (c *Context) GetLogger() *slog.Logger

GetLogger returns the *slog.Logger instance.

func (*Context) GetOrEmpty added in v0.2.2

func (c *Context) GetOrEmpty(key string) 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

HTML sends an 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 any) error

JSON sends a JSON response.

func (*Context) Latency added in v0.3.1

func (c *Context) Latency() time.Duration

Latency returns the duration of the request including the time it took to write the response, execute the middleware and the handler.

func (*Context) Locals

func (c *Context) Locals() map[string]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 string) any

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) ParamInt64 added in v1.5.0

func (c *Context) ParamInt64(key string, defaults ...int64) int64

ParamInt64 returns the value of the parameter as an int64.

func (*Context) ParamUint added in v1.5.0

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

ParamUint returns the value of the parameter as an unsigned integer

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.

func (*Context) QueryInt

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

QueryInt returns the value of the query as an integer.

func (*Context) QueryInt64 added in v1.5.0

func (c *Context) QueryInt64(key string, defaults ...int64) int64

QueryInt64 returns the value of the query as an int64.

func (*Context) QueryParser

func (c *Context) QueryParser(v any, 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

func (*Context) Redirect

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

Redirect redirects the request to the given URL. The 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

Router returns the router associated with the request.

func (*Context) SaveFile

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

SaveFile saves a multipart file to target.

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 string, value any)

Set stores a value in the context

func (*Context) SetContentType added in v1.9.0

func (c *Context) SetContentType(contentType string)

SetContentType sets the Content-Type header for the response.

func (*Context) SetHeader

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

SetHeader sets a header in the response

func (*Context) SetSkipBody added in v1.6.0

func (c *Context) SetSkipBody(enabled bool)

SetSkipBody toggles writing of the response body (for HEAD requests)

func (*Context) SkipBody added in v1.6.0

func (c *Context) SkipBody() bool

SkipBody indicates if the response body should be skipped

func (*Context) Status added in v0.2.6

func (c *Context) Status(status int) *Context

Status sets the status code of the response and returns the context allowing for chaining.

func (*Context) StatusCode added in v1.0.4

func (c *Context) StatusCode() int

StatusCode returns the status code written to the response.

func (*Context) String

func (c *Context) String(text string) 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

TranslateErrors returns English translations for validation errors.

func (*Context) URL added in v0.2.2

func (c *Context) URL() string

URL returns the request URL.

func (*Context) Value added in v1.7.0

func (c *Context) Value(key any) any

Value implements context.Context.

func (*Context) WrapWriter added in v1.6.0

func (c *Context) WrapWriter(fn func(http.ResponseWriter) http.ResponseWriter) (restore func())

WrapWriter applies a function to wrap the underlying writer safely and returns a restore function to revert to the previous writer.

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)

WriteHeader writes the response status code.

func (*Context) XML

func (c *Context) XML(data any) error

XML sends an XML response

type Error added in v1.7.1

type Error struct {
	Code           int               `json:"-"` // HTTP status code for the error
	Message        string            `json:"-"` // General error message, can be translated
	Fields         map[string]string `json:"-"` // Field-specific validation errors
	FormKind       FormErrorKind     `json:"-"` // Specific kind of form error
	FormField      string            `json:"-"` // Name of the form field that caused the error
	WrappedError   error             `json:"-"` // Original error for internal logging/debugging
	TranslationKey string            `json:"-"` // Key for looking up translated messages
}

Error defines a structured error for use within Rex.

func FormErr added in v1.7.1

func FormErr(formErr FormError) *Error

FormErr creates a new form error.

func NewError added in v1.7.1

func NewError(code int, message string) *Error

NewError creates a new generic error with a given message and optional status code.

func NewErrorWrap added in v1.7.1

func NewErrorWrap(code int, message string, err error) *Error

NewErrorWrap creates a new generic error wrapping an existing error.

func ValidationErr added in v1.7.1

func ValidationErr(fields map[string]string) *Error

ValidationErr creates a new validation error.

func (*Error) Error added in v1.7.1

func (e *Error) Error() string

Error makes Error implement the error interface.

func (*Error) ToResponse added in v1.7.1

func (e *Error) ToResponse() ErrorResponse

ToResponse converts the Error to a uniform ErrorResponse structure.

type ErrorDetail added in v1.7.1

type ErrorDetail struct {
	Message    string            `json:"message"`              // Human-readable error message
	Code       string            `json:"code,omitempty"`       // Error code for programmatic handling
	Details    map[string]any    `json:"details,omitempty"`    // Additional error context
	Validation *ValidationDetail `json:"validation,omitempty"` // Validation-specific errors
	Form       *FormDetail       `json:"form,omitempty"`       // Form-specific errors
}

ErrorDetail contains the actual error information.

type ErrorHandler added in v1.0.2

type ErrorHandler interface {
	Handle(c *Context, err error)
}

ErrorHandler interface allows for custom error handling.

type ErrorResponse added in v1.7.1

type ErrorResponse struct {
	Error ErrorDetail `json:"error"`
}

ErrorResponse represents the uniform JSON error response structure.

type FormDetail added in v1.7.1

type FormDetail struct {
	Kind  FormErrorKind `json:"kind"`            // Type of form error
	Field string        `json:"field,omitempty"` // Field that caused the error
}

FormDetail contains form-specific error information.

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 any) 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) *route

DELETE request.

func (*Group) GET added in v0.2.0

func (g *Group) GET(path string, handler HandlerFunc) *route

GET request.

func (*Group) Group

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

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) *route

PATCH request.

func (*Group) POST added in v0.2.0

func (g *Group) POST(path string, handler HandlerFunc) *route

POST request.

func (*Group) PUT added in v0.2.0

func (g *Group) PUT(path string, handler HandlerFunc) *route

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.

func (*Group) With added in v0.3.6

func (g *Group) With(middlewares ...Middleware) *route

With creates a route builder with the additional middleware applied.

type HandlerFunc

type HandlerFunc func(c *Context) error

HandlerFunc is the signature for route handlers that can return errors

type Map

type Map map[string]any

Map is a convenience alias for template and JSON response data.

type Middleware

type Middleware func(HandlerFunc) HandlerFunc

Middleware transforms one HandlerFunc into another.

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
}

RedirectOptions configures redirect status, params, and query parameters.

type ResponseWriter

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

ResponseWriter wraps http.ResponseWriter with additional functionality

func (*ResponseWriter) BytesWritten added in v1.6.0

func (w *ResponseWriter) BytesWritten() int

BytesWritten returns the number of bytes written to the body so far.

func (*ResponseWriter) Flush

func (w *ResponseWriter) Flush()

Flush implements http.Flusher for chunked responses and server-sent events.

func (*ResponseWriter) Header

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

Header returns the response headers.

func (*ResponseWriter) Hijack

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

Hijack lets the caller take over the connection.

func (*ResponseWriter) Push added in v1.4.0

func (w *ResponseWriter) Push(target string, opts *http.PushOptions) error

Push implements http.Pusher interface for HTTP/2 server push

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) SetSkipBody added in v1.6.0

func (w *ResponseWriter) SetSkipBody(enabled bool)

SetSkipBody toggles writing of response body (used for HEAD requests).

func (*ResponseWriter) SetStatus added in v1.9.0

func (w *ResponseWriter) SetStatus(status int)

SetStatus records a status code without writing headers immediately.

func (*ResponseWriter) Size

func (w *ResponseWriter) Size() int

Size returns the number of bytes written to the response body.

func (*ResponseWriter) SkipBody added in v1.6.0

func (w *ResponseWriter) SkipBody() bool

SkipBody returns whether the body should be skipped.

func (*ResponseWriter) Status

func (w *ResponseWriter) Status() int

Status returns the recorded HTTP status code.

func (*ResponseWriter) StatusCode added in v1.6.0

func (w *ResponseWriter) StatusCode() int

StatusCode returns the recorded status code.

func (*ResponseWriter) Unwrap

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

Unwrap exposes the underlying http.ResponseWriter for http.ResponseController support.

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.

func (*ResponseWriter) WriteString added in v1.9.0

func (w *ResponseWriter) WriteString(s string) (int, error)

WriteString writes a string response without forcing a string-to-byte allocation.

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) *route

CONNECT http request.

func (*Router) DELETE

func (r *Router) DELETE(pattern string, handler HandlerFunc) *route

DELETE registers a DELETE route.

func (*Router) FaviconFS

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

FaviconFS serves favicon.ico from fs at path.

func (*Router) File

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

File serves a single file while applying global middleware.

func (*Router) FileFS

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

FileFS serves a single file from fs while applying global middleware.

func (*Router) GET

func (r *Router) GET(pattern string, handler HandlerFunc) *route

GET registers a GET route.

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) *route

HEAD request.

func (*Router) InitContext added in v0.2.6

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

InitContext gets a Context from the pool and initializes it with the request and writer.

func (*Router) OPTIONS

func (r *Router) OPTIONS(pattern string, handler HandlerFunc) *route

OPTIONS registers an OPTIONS route.

func (*Router) PATCH

func (r *Router) PATCH(pattern string, handler HandlerFunc) *route

PATCH registers a PATCH route.

func (*Router) POST

func (r *Router) POST(pattern string, handler HandlerFunc) *route

POST registers a POST route.

func (*Router) PUT

func (r *Router) PUT(pattern string, handler HandlerFunc) *route

PUT registers a PUT route.

func (*Router) PutContext added in v0.2.6

func (r *Router) PutContext(c *Context)

PutContext returns a Context to the internal pool.

func (*Router) RegisterValidation

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

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

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

SetErrorHandler sets the error handler used for centralized error handling.

func (*Router) Static

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

Static serves static assets at prefix from 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)

StaticFS serves static assets from an http.FileSystem. Example:

app.StaticFS("/static", rex.CreateFileSystem(embedfs, "static"), 3600)

To enable caching, provide maxAge seconds for cache duration.

func (*Router) TRACE

func (r *Router) TRACE(pattern string, handler HandlerFunc) *route

TRACE http request.

func (*Router) ToHandler added in v1.0.1

func (r *Router) ToHandler(h HandlerFunc) http.Handler

ToHandler converts a HandlerFunc to an http.Handler.

func (*Router) Use

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

Use registers global middleware on the router.

func (*Router) With added in v0.3.5

func (r *Router) With(midleware ...Middleware) *route

With creates a route builder with the provided middleware.

func (*Router) WrapHandler added in v0.2.4

func (r *Router) WrapHandler(h http.Handler) HandlerFunc

WrapHandler wraps an http.Handler to be used as a rex.HandlerFunc

func (*Router) WrapMiddleware added in v0.2.4

func (r *Router) WrapMiddleware(middleware func(http.Handler) http.Handler) Middleware

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

type RouterOption

type RouterOption func(*Router)

RouterOption configures a Router during construction.

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 SkipLog added in v1.1.5

func SkipLog(skipLog func(c *Context) bool) RouterOption

SkipLog skips request logging when skipLog returns true.

func WithLogger

func WithLogger(logger *slog.Logger) RouterOption

WithLogger replaces the default slog.Logger with a custom logger.

func WithLoggerCallback added in v1.1.1

func WithLoggerCallback(callback func(c *Context) []any) RouterOption

WithLoggerCallback sets a callback function that should return an even number of additional user args to be appended to slog.Log arguments.

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)

SPAOption configures SPA handling behavior.

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
}

Server wraps http.Server with graceful shutdown helpers and option-based configuration.

func NewServer

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

NewServer creates a Server with HTTP/2 support.

func (*Server) Shutdown

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

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

type ServerOption

type ServerOption func(*Server)

ServerOption configures a Server.

func WithHTTP2Options

func WithHTTP2Options(http2ServerOptions http2.Server) ServerOption

WithHTTP2Options configures HTTP/2 server settings.

func WithIdleTimeout

func WithIdleTimeout(d time.Duration) ServerOption

WithIdleTimeout sets the server idle timeout.

func WithReadTimeout

func WithReadTimeout(d time.Duration) ServerOption

WithReadTimeout sets the server read timeout.

func WithTLSConfig

func WithTLSConfig(config *tls.Config) ServerOption

WithTLSConfig sets the TLS configuration and preserves HTTP/2 support.

func WithWriteTimeout

func WithWriteTimeout(d time.Duration) ServerOption

WithWriteTimeout sets the server write timeout.

type ValidationDetail added in v1.7.1

type ValidationDetail struct {
	Fields map[string]string `json:"fields"` // Field name -> error message
}

ValidationDetail contains field-level validation errors.

Directories

Path Synopsis
cmd
example command
server command
middleware
auth
Package auth provides session-based authentication middleware for the Rex router.
Package auth provides session-based authentication middleware for the Rex router.
brotli
Package brotli provides Brotli compression middleware for rex routers.
Package brotli provides Brotli compression middleware for rex routers.
cors
Package cors provides CORS middleware for rex routers.
Package cors provides CORS middleware for rex routers.
csrf
Package csrf provides CSRF protection middleware for rex routers.
Package csrf provides CSRF protection middleware for rex routers.
etag
Package etag provides ETag middleware for rex routers.
Package etag provides ETag middleware for rex routers.
flash
Package flash provides flash message helpers and middleware for rex routers.
Package flash provides flash message helpers and middleware for rex routers.
gzip
Package gzip provides gzip compression middleware for rex routers.
Package gzip provides gzip compression middleware for rex routers.
logger
Package logger provides request logging middleware for rex routers.
Package logger provides request logging middleware for rex routers.
ratelimit
Package ratelimit provides rate limiting middleware for rex routers.
Package ratelimit provides rate limiting middleware for rex routers.
recovery
Package recovery provides panic recovery middleware for rex routers.
Package recovery provides panic recovery middleware for rex routers.
requestid
Package requestid provides request ID middleware for rex routers.
Package requestid provides request ID middleware for rex routers.
security
Package security provides security header middleware for rex routers.
Package security provides security header middleware for rex routers.
Package sse provides server-sent events helpers for rex routers.
Package sse provides server-sent events helpers for rex routers.
Package test provides HTTP testing helpers for rex routers.
Package test provides HTTP testing helpers for rex routers.

Jump to

Keyboard shortcuts

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