router

package
v1.2.8 Latest Latest
Warning

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

Go to latest
Published: Apr 22, 2025 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package router provides a flexible and feature-rich HTTP routing framework. It supports middleware, sub-routers, generic handlers, and various configuration options.

Package router provides a flexible and feature-rich HTTP routing framework. It supports middleware, sub-routers, generic handlers, and various configuration options.

Index

Constants

View Source
const (
	// ParamsKey is the key used to store httprouter.Params in the request context.
	// This allows route parameters to be accessed from handlers and middleware.
	ParamsKey contextKey = "params"
)

Variables

This section is empty.

Functions

func ClientIPMiddleware added in v1.1.14

func ClientIPMiddleware[T comparable, U any](config *IPConfig) func(http.Handler) http.Handler

ClientIPMiddleware creates a middleware that extracts the client IP from the request and adds it to the SRouterContext. T is the User ID type (comparable), U is the User object type (any). It stores the IP address in the SRouterContext.

func GetParam

func GetParam(r *http.Request, name string) string

GetParam retrieves a specific parameter from the request context. It's a convenience function that combines GetParams and ByName.

func GetParams

func GetParams(r *http.Request) httprouter.Params

GetParams retrieves the httprouter.Params from the request context. This allows handlers to access route parameters extracted from the URL.

func RegisterGenericRoute

func RegisterGenericRoute[Req any, Resp any, UserID comparable, User any](
	r *Router[UserID, User],
	route RouteConfig[Req, Resp],

	effectiveTimeout time.Duration,
	effectiveMaxBodySize int64,
	effectiveRateLimit *common.RateLimitConfig[UserID, User],
)

RegisterGenericRoute registers a route with generic request and response types. This is a standalone function rather than a method because Go methods cannot have type parameters. It creates a handler that uses the codec to decode the request and encode the response, applies middleware using the provided effective settings, and registers the route with the router.

func RegisterGenericRouteOnSubRouter added in v1.1.2

func RegisterGenericRouteOnSubRouter[Req any, Resp any, UserID comparable, User any](
	r *Router[UserID, User],
	pathPrefix string,
	route RouteConfig[Req, Resp],
) error

RegisterGenericRouteOnSubRouter registers a generic route intended to be part of a sub-router. It finds the SubRouterConfig matching the provided pathPrefix, applies relevant overrides and middleware, prefixes the route's path, and then registers it using RegisterGenericRoute. This function should be called *after* NewRouter has been called.

func RegisterSubRouterWithSubRouter added in v1.0.7

func RegisterSubRouterWithSubRouter(parent *SubRouterConfig, child SubRouterConfig)

RegisterSubRouterWithSubRouter registers a nested SubRouter with a parent SubRouter This is a helper function that adds a SubRouter to the parent SubRouter's SubRouters field

Types

type AuthLevel added in v1.0.0

type AuthLevel int

AuthLevel defines the authentication level for a route. It determines how authentication is handled for the route.

const (
	// NoAuth indicates that no authentication is required for the route.
	// The route will be accessible without any authentication.
	NoAuth AuthLevel = iota

	// AuthOptional indicates that authentication is optional for the route.
	// If authentication credentials are provided, they will be validated and the user
	// will be added to the request context if valid. If no credentials are provided
	// or they are invalid, the request will still proceed without a user in the context.
	AuthOptional

	// AuthRequired indicates that authentication is required for the route.
	// If authentication fails, the request will be rejected with a 401 Unauthorized response.
	// If authentication succeeds, the user will be added to the request context.
	AuthRequired
)

func Ptr added in v1.1.2

func Ptr(level AuthLevel) *AuthLevel

Ptr returns a pointer to the given AuthLevel value. Useful for setting AuthLevel fields in configurations.

type CORSConfig added in v1.2.7

type CORSConfig struct {
	Origins          []string      // Allowed origins (e.g., "http://example.com", "*"). Required.
	Methods          []string      // Allowed methods (e.g., "GET", "POST"). Defaults to simple methods if empty.
	Headers          []string      // Allowed headers. Defaults to simple headers if empty.
	ExposeHeaders    []string      // Headers the browser is allowed to access.
	AllowCredentials bool          // Whether to allow credentials (cookies, authorization headers).
	MaxAge           time.Duration // How long the results of a preflight request can be cached.
}

CORSConfig defines the configuration for Cross-Origin Resource Sharing (CORS). It allows customization of which origins, methods, headers, and credentials are allowed for cross-origin requests, and which headers can be exposed to the client-side script.

type Codec

type Codec[T any, U any] interface {
	// NewRequest creates a new zero-value instance of the request type T.
	// This is used by the framework to get an instance for decoding, avoiding reflection.
	NewRequest() T

	// Decode extracts and deserializes data from an HTTP request body into a value of type T.
	// The type T represents the request data type.
	Decode(r *http.Request) (T, error)

	// DecodeBytes extracts and deserializes data from a byte slice into a value of type T.
	// This is used for source types where the data is already extracted (e.g., query/path parameters).
	// The type T represents the request data type.
	DecodeBytes(data []byte) (T, error)

	// Encode serializes a value of type U and writes it to the HTTP response.
	// It converts the Go value to the wire format (e.g., JSON, Protocol Buffers) and
	// sets appropriate headers (e.g., Content-Type). If the serialization fails, it returns an error.
	// The type U represents the response data type.
	Encode(w http.ResponseWriter, resp U) error
}

Codec defines an interface for marshaling and unmarshaling request and response data. It provides methods for creating new request objects, decoding request data, and encoding response data. This allows for different data formats (e.g., JSON, Protocol Buffers). The framework includes implementations for JSON and Protocol Buffers in the codec package.

type GenericHandler

type GenericHandler[T any, U any] func(r *http.Request, data T) (U, error)

GenericHandler defines a handler function with generic request and response types. It takes an http.Request and a typed request data object, and returns a typed response object and an error. This allows for strongly-typed request and response handling. The type parameters T and U represent the request and response data types respectively. When used with RegisterGenericRoute, the framework automatically handles decoding the request and encoding the response using the specified Codec.

type GenericRouteRegistrationFunc added in v1.1.2

type GenericRouteRegistrationFunc[T comparable, U any] func(r *Router[T, U], sr SubRouterConfig)

GenericRouteRegistrationFunc defines the function signature for registering a generic route declaratively. This function is stored in SubRouterConfig.Routes and called during router initialization. It captures the specific generic types and calls the appropriate registration logic.

func NewGenericRouteDefinition added in v1.1.2

func NewGenericRouteDefinition[Req any, Resp any, UserID comparable, User any](
	route RouteConfig[Req, Resp],
) GenericRouteRegistrationFunc[UserID, User]

NewGenericRouteDefinition creates a GenericRouteRegistrationFunc for declarative configuration. It captures the specific RouteConfig[Req, Resp] and returns a function that, when called by registerSubRouter, calculates effective settings and registers the generic route.

type HTTPError

type HTTPError struct {
	StatusCode int    // HTTP status code (e.g., 400, 404, 500)
	Message    string // Error message to be sent in the response body
}

HTTPError represents an HTTP error with a status code and message. It can be used to return specific HTTP errors from handlers. When returned from a handler, the router will use the status code and message to generate an appropriate HTTP response. This allows handlers to control the exact error response sent to clients.

func NewHTTPError

func NewHTTPError(statusCode int, message string) *HTTPError

NewHTTPError creates a new HTTPError with the specified status code and message. It's a convenience function for creating HTTP errors in handlers.

func (*HTTPError) Error

func (e *HTTPError) Error() string

Error implements the error interface. It returns a string representation of the HTTP error in the format "status: message".

type HttpMethod added in v1.1.11

type HttpMethod string

HttpMethod defines the type for HTTP methods.

const (
	MethodGet     HttpMethod = http.MethodGet
	MethodHead    HttpMethod = http.MethodHead
	MethodPost    HttpMethod = http.MethodPost
	MethodPut     HttpMethod = http.MethodPut
	MethodPatch   HttpMethod = http.MethodPatch // RFC 5789
	MethodDelete  HttpMethod = http.MethodDelete
	MethodConnect HttpMethod = http.MethodConnect
	MethodOptions HttpMethod = http.MethodOptions
	MethodTrace   HttpMethod = http.MethodTrace
)

Constants for standard HTTP methods.

type IPConfig added in v1.1.14

type IPConfig struct {
	// Source specifies where to extract the client IP from.
	Source IPSourceType

	// CustomHeader is the name of the custom header to use when Source is IPSourceCustomHeader
	CustomHeader string

	// TrustProxy determines whether to trust proxy headers like X-Forwarded-For
	// If false, RemoteAddr will be used as a fallback for all sources
	TrustProxy bool
}

IPConfig defines configuration for IP extraction.

func DefaultIPConfig added in v1.1.14

func DefaultIPConfig() *IPConfig

DefaultIPConfig returns the default IP configuration.

type IPSourceType added in v1.1.14

type IPSourceType string

IPSourceType defines the source for client IP addresses.

const (
	// IPSourceRemoteAddr uses the request's RemoteAddr field
	IPSourceRemoteAddr IPSourceType = "remote_addr"

	// IPSourceXForwardedFor uses the X-Forwarded-For header
	IPSourceXForwardedFor IPSourceType = "x_forwarded_for"

	// IPSourceXRealIP uses the X-Real-IP header
	IPSourceXRealIP IPSourceType = "x_real_ip"

	// IPSourceCustomHeader uses a custom header specified in the configuration
	IPSourceCustomHeader IPSourceType = "custom_header"
)

type MetricsConfig added in v1.0.3

type MetricsConfig struct {
	// Collector is the metrics collector to use.
	// If nil, a default collector will be used if metrics are enabled.
	Collector any // metrics.Collector

	// MiddlewareFactory is the factory for creating metrics middleware.
	// If nil, a default middleware factory will be used if metrics are enabled.
	MiddlewareFactory any // metrics.MiddlewareFactory

	// Namespace for metrics.
	Namespace string

	// Subsystem for metrics.
	Subsystem string

	// EnableLatency enables latency metrics.
	EnableLatency bool

	// EnableThroughput enables throughput metrics.
	EnableThroughput bool

	// EnableQPS enables queries per second metrics.
	EnableQPS bool

	// EnableErrors enables error metrics.
	EnableErrors bool
}

MetricsConfig defines the configuration for metrics collection. It allows customization of how metrics are collected and exposed.

type Middleware

type Middleware = common.Middleware

Middleware is an alias for common.Middleware. It represents a function that wraps an http.Handler to provide additional functionality.

type PrometheusConfig

type PrometheusConfig struct{}

PrometheusConfig is removed in favor of MetricsConfig with v2 metrics system. This type is kept for reference but should not be used. Deprecated: Use MetricsConfig instead.

type RouteConfig

type RouteConfig[T any, U any] struct {
	Path        string                            // Route path (will be prefixed with sub-router path prefix if applicable)
	Methods     []HttpMethod                      // HTTP methods this route handles (use constants like MethodGet)
	AuthLevel   *AuthLevel                        // Authentication level for this route (NoAuth, AuthOptional, or AuthRequired). If nil, inherits from sub-router or defaults to NoAuth.
	Timeout     time.Duration                     // Override timeout for this specific route
	MaxBodySize int64                             // Override max body size for this specific route
	RateLimit   *common.RateLimitConfig[any, any] // Use common.RateLimitConfig // Rate limit for this specific route
	Codec       Codec[T, U]                       // Codec for marshaling/unmarshaling request and response
	Handler     GenericHandler[T, U]              // Generic handler function
	Middlewares []common.Middleware               // Middlewares applied to this specific route
	SourceType  SourceType                        // How to retrieve request data (defaults to Body)
	SourceKey   string                            // Query parameter name (only used for query parameters)
	Sanitizer   func(T) (T, error)                // Optional sanitizer function applied after decoding
}

RouteConfig defines a route with generic request and response types. It extends RouteConfigBase with type parameters for request and response data, allowing for strongly-typed handlers and automatic marshaling/unmarshaling.

type RouteConfigBase

type RouteConfigBase struct {
	Path        string                            // Route path (will be prefixed with sub-router path prefix if applicable)
	Methods     []HttpMethod                      // HTTP methods this route handles (use constants like MethodGet)
	AuthLevel   *AuthLevel                        // Authentication level for this route (NoAuth, AuthOptional, or AuthRequired). If nil, inherits from sub-router or defaults to NoAuth.
	Timeout     time.Duration                     // Override timeout for this specific route
	MaxBodySize int64                             // Override max body size for this specific route
	RateLimit   *common.RateLimitConfig[any, any] // Use common.RateLimitConfig // Rate limit for this specific route
	Handler     http.HandlerFunc                  // Standard HTTP handler function
	Middlewares []common.Middleware               // Middlewares applied to this specific route
}

RouteConfigBase defines the base configuration for a route without generics. It includes settings for path, HTTP methods, authentication, timeouts, and middleware.

type Router

type Router[T comparable, U any] struct {
	// contains filtered or unexported fields
}

Router is the main router struct that implements http.Handler. It provides routing, middleware support, graceful shutdown, and other features.

func NewRouter

func NewRouter[T comparable, U any](config RouterConfig, authFunction func(context.Context, string) (*U, bool), userIdFromuserFunction func(*U) T) *Router[T, U]

NewRouter creates a new Router with the given configuration. It initializes the underlying httprouter, sets up logging, and registers routes from sub-routers.

func (*Router[T, U]) RegisterRoute

func (r *Router[T, U]) RegisterRoute(route RouteConfigBase)

RegisterRoute registers a route with the router. It creates a handler with all middlewares applied and registers it with the underlying httprouter. For generic routes with type parameters, use RegisterGenericRoute function instead.

func (*Router[T, U]) RegisterSubRouter added in v1.0.7

func (r *Router[T, U]) RegisterSubRouter(sr SubRouterConfig)

RegisterSubRouter registers a sub-router with the router. It applies the sub-router's path prefix to all routes and registers them with the router. This is an exported wrapper for the unexported registerSubRouter method.

func (*Router[T, U]) ServeHTTP

func (r *Router[T, U]) ServeHTTP(w http.ResponseWriter, req *http.Request)

ServeHTTP implements the http.Handler interface. It handles HTTP requests by applying CORS, client IP extraction, metrics, tracing, and then delegating to the underlying httprouter.

func (*Router[T, U]) Shutdown

func (r *Router[T, U]) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the router. It stops accepting new requests and waits for existing requests to complete.

type RouterConfig

type RouterConfig struct {
	ServiceName         string                            // Name of the service, used for metrics tagging etc.
	Logger              *zap.Logger                       // Logger for all router operations
	GlobalTimeout       time.Duration                     // Default response timeout for all routes
	GlobalMaxBodySize   int64                             // Default maximum request body size in bytes
	GlobalRateLimit     *common.RateLimitConfig[any, any] // Use common.RateLimitConfig // Default rate limit for all routes
	IPConfig            *IPConfig                         // Configuration for client IP extraction
	EnableMetrics       bool                              // Enable metrics collection
	EnableTraceLogging  bool                              // Enable trace logging
	TraceLoggingUseInfo bool                              // Use Info level for trace logging
	TraceIDBufferSize   int                               // Buffer size for trace ID generator (0 disables trace ID)
	MetricsConfig       *MetricsConfig                    // Metrics configuration (optional)
	SubRouters          []SubRouterConfig                 // Sub-routers with their own configurations
	Middlewares         []common.Middleware               // Global middlewares applied to all routes
	AddUserObjectToCtx  bool                              // Add user object to context
	CORSConfig          *CORSConfig                       // CORS configuration (optional, if nil CORS is disabled)
}

RouterConfig defines the global configuration for the router. It includes settings for logging, timeouts, metrics, and middleware.

type SourceType added in v1.0.5

type SourceType int

SourceType defines where to retrieve request data from. It determines how the request data is extracted and decoded.

const (
	// Body retrieves data from the request body (default).
	// The request body is read and passed directly to the codec for decoding.
	Body SourceType = iota

	// Base64QueryParameter retrieves data from a base64-encoded query parameter.
	// The query parameter value is decoded from base64 before being passed to the codec.
	Base64QueryParameter

	// Base62QueryParameter retrieves data from a base62-encoded query parameter.
	// The query parameter value is decoded from base62 before being passed to the codec.
	Base62QueryParameter

	// Base64PathParameter retrieves data from a base64-encoded path parameter.
	// The path parameter value is decoded from base64 before being passed to the codec.
	Base64PathParameter

	// Base62PathParameter retrieves data from a base62-encoded path parameter.
	// The path parameter value is decoded from base62 before being passed to the codec.
	Base62PathParameter

	// Empty does not decode anything. It acts as a noop for decoding.
	Empty
)

type SubRouterConfig

type SubRouterConfig struct {
	PathPrefix          string                            // Common path prefix for all routes in this sub-router
	TimeoutOverride     time.Duration                     // Override global timeout for all routes in this sub-router
	MaxBodySizeOverride int64                             // Override global max body size for all routes in this sub-router
	RateLimitOverride   *common.RateLimitConfig[any, any] // Use common.RateLimitConfig // Override global rate limit for all routes in this sub-router
	Routes              []any                             // Routes in this sub-router. Can contain RouteConfigBase or GenericRouteRegistrationFunc.
	Middlewares         []common.Middleware               // Middlewares applied to all routes in this sub-router
	// SubRouters is a slice of nested sub-routers
	// This allows for creating a hierarchy of sub-routers
	SubRouters []SubRouterConfig // Nested sub-routers
	AuthLevel  *AuthLevel        // Default authentication level for all routes in this sub-router (overridden by route-specific AuthLevel)
}

SubRouterConfig defines configuration for a group of routes with a common path prefix. This allows for organizing routes into logical groups and applying shared configuration.

Directories

Path Synopsis
internal

Jump to

Keyboard shortcuts

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