Documentation
¶
Overview ¶
Package chimux provides a Chi-based HTTP router module for the modular framework.
This module wraps the popular Go Chi router and integrates it with the modular framework's service system, providing HTTP routing, middleware management, CORS support, and tenant-aware configuration.
Features ¶
The chimux module offers the following capabilities:
- HTTP routing with pattern matching and parameter extraction
- Middleware chain management with automatic service discovery
- CORS configuration with per-tenant customization
- Base path support for sub-application mounting
- Tenant-aware configuration for multi-tenant applications
- Service registration for dependency injection
Requirements ¶
The chimux module requires a TenantApplication to operate. It will return an error if initialized with a regular Application instance.
Configuration ¶
The module can be configured through the ChiMuxConfig structure:
config := &ChiMuxConfig{ AllowedOrigins: []string{"https://example.com", "https://app.example.com"}, AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"}, AllowedHeaders: []string{"Origin", "Accept", "Content-Type", "Authorization"}, AllowCredentials: true, MaxAge: 3600, Timeout: 30000, BasePath: "/api/v1", }
Service Registration ¶
The module registers multiple services for different use cases:
- "chimux.router": The full ChiMuxModule instance
- "router": BasicRouter interface for simple routing needs
- "chi.router": Direct access to the underlying Chi router
Usage Examples ¶
Basic routing:
router := app.GetService("router").(chimux.BasicRouter) router.Get("/users", getUsersHandler) router.Post("/users", createUserHandler) router.Get("/users/{id}", getUserHandler)
Advanced routing with Chi features:
chiRouter := app.GetService("chi.router").(chi.Router) chiRouter.Route("/api", func(r chi.Router) { r.Use(authMiddleware) r.Get("/protected", protectedHandler) })
Middleware integration:
// Modules implementing MiddlewareProvider are automatically discovered type MyModule struct{} func (m *MyModule) ProvideMiddleware() []chimux.Middleware { return []chimux.Middleware{ myCustomMiddleware, loggingMiddleware, } }
Tenant Support ¶
The module supports tenant-specific configurations:
// Different tenants can have different CORS settings tenant1Config := &ChiMuxConfig{ AllowedOrigins: []string{"https://tenant1.example.com"}, } tenant2Config := &ChiMuxConfig{ AllowedOrigins: []string{"https://tenant2.example.com"}, }
Index ¶
- Constants
- Variables
- func NewChiMuxModule() modular.Module
- type BasicRouter
- type ChiMuxConfig
- type ChiMuxModule
- func (m *ChiMuxModule) ChiRouter() chi.Router
- func (m *ChiMuxModule) Connect(pattern string, h http.HandlerFunc)
- func (m *ChiMuxModule) Constructor() modular.ModuleConstructor
- func (m *ChiMuxModule) Delete(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) Dependencies() []string
- func (m *ChiMuxModule) Get(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) GetTenantConfig(tenantID modular.TenantID) *ChiMuxConfig
- func (m *ChiMuxModule) Group(fn func(chi.Router)) chi.Router
- func (m *ChiMuxModule) Handle(pattern string, handler http.Handler)
- func (m *ChiMuxModule) HandleFunc(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) Head(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) Init(app modular.Application) error
- func (m *ChiMuxModule) Match(rctx *chi.Context, method, path string) bool
- func (m *ChiMuxModule) Method(method, pattern string, h http.Handler)
- func (m *ChiMuxModule) MethodFunc(method, pattern string, h http.HandlerFunc)
- func (m *ChiMuxModule) MethodNotAllowed(h http.HandlerFunc)
- func (m *ChiMuxModule) Middlewares() chi.Middlewares
- func (m *ChiMuxModule) Mount(pattern string, handler http.Handler)
- func (m *ChiMuxModule) Name() string
- func (m *ChiMuxModule) NotFound(h http.HandlerFunc)
- func (m *ChiMuxModule) OnTenantRegistered(tenantID modular.TenantID)
- func (m *ChiMuxModule) OnTenantRemoved(tenantID modular.TenantID)
- func (m *ChiMuxModule) Options(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) Patch(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) Post(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) ProvidesServices() []modular.ServiceProvider
- func (m *ChiMuxModule) Put(pattern string, handler http.HandlerFunc)
- func (m *ChiMuxModule) RegisterConfig(app modular.Application) error
- func (m *ChiMuxModule) RequiresServices() []modular.ServiceDependency
- func (m *ChiMuxModule) Route(pattern string, fn func(chi.Router)) chi.Router
- func (m *ChiMuxModule) Routes() []chi.Route
- func (m *ChiMuxModule) ServeHTTP(w http.ResponseWriter, r *http.Request)
- func (m *ChiMuxModule) Start(context.Context) error
- func (m *ChiMuxModule) Stop(context.Context) error
- func (m *ChiMuxModule) Trace(pattern string, h http.HandlerFunc)
- func (m *ChiMuxModule) Use(middlewares ...func(http.Handler) http.Handler)
- func (m *ChiMuxModule) With(middlewares ...func(http.Handler) http.Handler) chi.Router
- type ChiRouterService
- type Middleware
- type MiddlewareProvider
- type Router
- type RouterService
Constants ¶
const ModuleName = "chimux"
ModuleName is the unique identifier for the chimux module.
const ServiceName = "chimux.router"
ServiceName is the name of the primary service provided by this module. Use this to request the chimux router service through dependency injection.
Variables ¶
var ( // ErrRequiresTenantApplication is returned when the module is initialized // with a non-tenant application. The chimux module requires tenant support // for proper multi-tenant routing and configuration. ErrRequiresTenantApplication = errors.New("chimux module requires a TenantApplication") )
Error definitions for the chimux module.
Functions ¶
func NewChiMuxModule ¶
NewChiMuxModule creates a new instance of the chimux module. This is the primary constructor for the chimux module and should be used when registering the module with the application.
Example:
app.RegisterModule(chimux.NewChiMuxModule())
Types ¶
type BasicRouter ¶
type BasicRouter interface { // Get registers a GET handler for the specified pattern. // The pattern supports Chi's URL parameter syntax: "/users/{id}" Get(pattern string, handler http.HandlerFunc) // Post registers a POST handler for the specified pattern. Post(pattern string, handler http.HandlerFunc) // Put registers a PUT handler for the specified pattern. Put(pattern string, handler http.HandlerFunc) // Delete registers a DELETE handler for the specified pattern. Delete(pattern string, handler http.HandlerFunc) // Patch registers a PATCH handler for the specified pattern. Patch(pattern string, handler http.HandlerFunc) // Head registers a HEAD handler for the specified pattern. Head(pattern string, handler http.HandlerFunc) // Options registers an OPTIONS handler for the specified pattern. Options(pattern string, handler http.HandlerFunc) // Handle registers a generic HTTP handler for the specified pattern. // Use this when you need to handle multiple HTTP methods in one handler // or when working with existing http.Handler implementations. Handle(pattern string, handler http.Handler) // HandleFunc registers a generic HTTP handler function for the specified pattern. HandleFunc(pattern string, handler http.HandlerFunc) // Mount attaches another http.Handler at the specified pattern. // This is useful for mounting sub-applications or third-party handlers. // The mounted handler will receive requests with the mount pattern stripped. Mount(pattern string, handler http.Handler) // Use appends one or more middleware functions to the middleware chain. // Middleware is applied in the order it's added and affects all routes // registered after the middleware is added. Use(middlewares ...func(http.Handler) http.Handler) // ServeHTTP implements the http.Handler interface, allowing the router // to be used directly as an HTTP handler or mounted in other routers. ServeHTTP(w http.ResponseWriter, r *http.Request) }
BasicRouter defines the essential router interface that most modules need. This interface provides access to HTTP method handlers and basic routing functionality without exposing Chi-specific methods that can be problematic for interface abstraction.
Use this interface when you need simple routing functionality and don't require Chi's advanced features like Route groups or sub-routers.
type ChiMuxConfig ¶
type ChiMuxConfig struct { // AllowedOrigins specifies the list of allowed origins for CORS requests. // Use ["*"] to allow all origins, or specify exact origins for security. // Multiple origins can be specified for multi-domain applications. // Default: ["*"] AllowedOrigins []string `yaml:"allowed_origins" default:"[\"*\"]" desc:"List of allowed origins for CORS requests." env:"ALLOWED_ORIGINS"` // AllowedMethods specifies the list of allowed HTTP methods for CORS requests. // This controls which HTTP methods browsers are allowed to use in // cross-origin requests. Common methods include GET, POST, PUT, DELETE, OPTIONS. // Default: ["GET", "POST", "PUT", "DELETE", "OPTIONS"] AllowedMethods []string `` /* 141-byte string literal not displayed */ // AllowedHeaders specifies the list of allowed request headers for CORS requests. // This controls which headers browsers are allowed to send in cross-origin requests. // Common headers include Origin, Accept, Content-Type, Authorization. // Default: ["Origin", "Accept", "Content-Type", "X-Requested-With", "Authorization"] AllowedHeaders []string `` /* 174-byte string literal not displayed */ // AllowCredentials determines whether cookies, authorization headers, // and TLS client certificates are allowed in CORS requests. // Set to true when your API needs to handle authenticated cross-origin requests. // Default: false AllowCredentials bool `yaml:"allow_credentials" default:"false" desc:"Allow credentials in CORS requests." env:"ALLOW_CREDENTIALS"` // MaxAge specifies the maximum age for CORS preflight cache in seconds. // This controls how long browsers can cache preflight request results, // reducing the number of preflight requests for repeated cross-origin calls. // Default: 300 (5 minutes) MaxAge int `yaml:"max_age" default:"300" desc:"Maximum age for CORS preflight cache in seconds." env:"MAX_AGE"` // Timeout specifies the default request timeout in milliseconds. // This sets a default timeout for request processing, though individual // handlers may override this with their own timeout logic. // Default: 60000 (60 seconds) Timeout int `yaml:"timeout" default:"60000" desc:"Default request timeout." env:"TIMEOUT"` // BasePath specifies a base path prefix for all routes registered through this module. // When set, all routes will be prefixed with this path. Useful for mounting // the application under a sub-path or for API versioning. // Example: "/api/v1" would make a route "/users" accessible as "/api/v1/users" // Default: "" (no prefix) BasePath string `yaml:"basepath" desc:"A base path prefix for all routes registered through this module." env:"BASE_PATH"` }
ChiMuxConfig holds the configuration for the chimux module. This structure contains all the settings needed to configure CORS, request handling, and routing behavior for the Chi router.
Configuration can be provided through JSON, YAML, or environment variables. The struct tags define the mapping for each configuration source and default values.
Example YAML configuration:
allowed_origins: - "https://example.com" - "https://app.example.com" allowed_methods: - "GET" - "POST" - "PUT" - "DELETE" allowed_headers: - "Origin" - "Accept" - "Content-Type" - "Authorization" allow_credentials: true max_age: 3600 timeout: 30000 basepath: "/api/v1"
Example environment variables:
CHIMUX_ALLOWED_ORIGINS=https://example.com,https://app.example.com CHIMUX_ALLOW_CREDENTIALS=true CHIMUX_BASE_PATH=/api/v1
func (*ChiMuxConfig) Validate ¶
func (c *ChiMuxConfig) Validate() error
Validate implements the modular.ConfigValidator interface. This method is called during configuration loading to ensure the configuration values are valid and consistent.
Currently performs basic validation but can be extended to include:
- URL validation for allowed origins
- Timeout range validation
- Base path format validation
type ChiMuxModule ¶
type ChiMuxModule struct {
// contains filtered or unexported fields
}
ChiMuxModule provides HTTP routing functionality using the Chi router library. It integrates Chi with the modular framework's service system and provides tenant-aware configuration, middleware management, and CORS support.
The module implements the following interfaces:
- modular.Module: Basic module lifecycle
- modular.Configurable: Configuration management
- modular.ServiceAware: Service dependency management
- modular.Startable: Startup logic
- modular.Stoppable: Shutdown logic
- modular.TenantAwareModule: Tenant lifecycle management
- BasicRouter: Basic HTTP routing
- Router: Extended Chi router functionality
- ChiRouterService: Direct Chi router access
The router is thread-safe and supports concurrent request handling.
func (*ChiMuxModule) ChiRouter ¶
func (m *ChiMuxModule) ChiRouter() chi.Router
ChiRouter returns the underlying chi.Router instance
func (*ChiMuxModule) Connect ¶
func (m *ChiMuxModule) Connect(pattern string, h http.HandlerFunc)
func (*ChiMuxModule) Constructor ¶
func (m *ChiMuxModule) Constructor() modular.ModuleConstructor
Constructor provides a dependency injection constructor for the module. This method is used by the dependency injection system to create the module instance with any required services.
func (*ChiMuxModule) Delete ¶
func (m *ChiMuxModule) Delete(pattern string, handler http.HandlerFunc)
Delete registers a DELETE handler for the pattern
func (*ChiMuxModule) Dependencies ¶
func (m *ChiMuxModule) Dependencies() []string
Dependencies returns the names of modules this module depends on. The chimux module has no hard dependencies and can be started independently. However, it will automatically discover and integrate with modules that implement MiddlewareProvider.
func (*ChiMuxModule) Get ¶
func (m *ChiMuxModule) Get(pattern string, handler http.HandlerFunc)
Get registers a GET handler for the pattern
func (*ChiMuxModule) GetTenantConfig ¶
func (m *ChiMuxModule) GetTenantConfig(tenantID modular.TenantID) *ChiMuxConfig
GetTenantConfig retrieves the loaded configuration for a specific tenant. Returns the tenant-specific configuration if available, or the base configuration as a fallback.
This method is useful for modules that need to access tenant-specific router configurations at runtime.
func (*ChiMuxModule) Group ¶
func (m *ChiMuxModule) Group(fn func(chi.Router)) chi.Router
func (*ChiMuxModule) Handle ¶
func (m *ChiMuxModule) Handle(pattern string, handler http.Handler)
Handle registers a handler for a specific pattern
func (*ChiMuxModule) HandleFunc ¶
func (m *ChiMuxModule) HandleFunc(pattern string, handler http.HandlerFunc)
HandleFunc registers a handler function for a specific pattern
func (*ChiMuxModule) Head ¶
func (m *ChiMuxModule) Head(pattern string, handler http.HandlerFunc)
Head registers a HEAD handler for the pattern
func (*ChiMuxModule) Init ¶
func (m *ChiMuxModule) Init(app modular.Application) error
Init initializes the chimux module with the application context. This method is called after all modules have been registered and their configurations loaded. It sets up the Chi router, applies middleware, and configures CORS settings.
The initialization process:
- Validates that the application supports tenants
- Loads the module configuration
- Creates and configures the Chi router
- Sets up default middleware (RequestID, RealIP, Logger, Recoverer)
- Applies CORS middleware based on configuration
- Discovers and applies middleware from other modules
Requirements:
- Must be used with a TenantApplication
- Configuration must be properly loaded
func (*ChiMuxModule) Match ¶
func (m *ChiMuxModule) Match(rctx *chi.Context, method, path string) bool
func (*ChiMuxModule) MethodFunc ¶
func (m *ChiMuxModule) MethodFunc(method, pattern string, h http.HandlerFunc)
func (*ChiMuxModule) MethodNotAllowed ¶
func (m *ChiMuxModule) MethodNotAllowed(h http.HandlerFunc)
func (*ChiMuxModule) Middlewares ¶
func (m *ChiMuxModule) Middlewares() chi.Middlewares
func (*ChiMuxModule) Mount ¶
func (m *ChiMuxModule) Mount(pattern string, handler http.Handler)
Mount attaches another http.Handler at the given pattern
func (*ChiMuxModule) Name ¶
func (m *ChiMuxModule) Name() string
Name returns the unique identifier for this module. This name is used for service registration, dependency resolution, and configuration section identification.
func (*ChiMuxModule) NotFound ¶
func (m *ChiMuxModule) NotFound(h http.HandlerFunc)
func (*ChiMuxModule) OnTenantRegistered ¶
func (m *ChiMuxModule) OnTenantRegistered(tenantID modular.TenantID)
OnTenantRegistered is called when a new tenant is registered. This method is part of the TenantAwareModule interface and allows the chimux module to prepare tenant-specific configurations.
The actual configuration loading is deferred to avoid deadlocks during the tenant registration process.
func (*ChiMuxModule) OnTenantRemoved ¶
func (m *ChiMuxModule) OnTenantRemoved(tenantID modular.TenantID)
OnTenantRemoved is called when a tenant is removed. This method cleans up any tenant-specific configurations and resources.
func (*ChiMuxModule) Options ¶
func (m *ChiMuxModule) Options(pattern string, handler http.HandlerFunc)
Options registers an OPTIONS handler for the pattern
func (*ChiMuxModule) Patch ¶
func (m *ChiMuxModule) Patch(pattern string, handler http.HandlerFunc)
Patch registers a PATCH handler for the pattern
func (*ChiMuxModule) Post ¶
func (m *ChiMuxModule) Post(pattern string, handler http.HandlerFunc)
Post registers a POST handler for the pattern
func (*ChiMuxModule) ProvidesServices ¶
func (m *ChiMuxModule) ProvidesServices() []modular.ServiceProvider
ProvidesServices declares services provided by this module. The chimux module provides multiple service interfaces to accommodate different usage patterns and integration needs.
Provided services:
- "chimux.router": The full ChiMuxModule instance
- "router": BasicRouter interface for simple routing needs
- "chi.router": Direct access to the underlying Chi router
func (*ChiMuxModule) Put ¶
func (m *ChiMuxModule) Put(pattern string, handler http.HandlerFunc)
Put registers a PUT handler for the pattern
func (*ChiMuxModule) RegisterConfig ¶
func (m *ChiMuxModule) RegisterConfig(app modular.Application) error
RegisterConfig registers the module's configuration structure. This method is called during application initialization to register the default configuration values for the chimux module.
Default configuration:
- AllowedOrigins: ["*"] (all origins allowed)
- AllowedMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS"]
- AllowedHeaders: ["Origin", "Accept", "Content-Type", "X-Requested-With", "Authorization"]
- AllowCredentials: false
- MaxAge: 300 seconds (5 minutes)
- Timeout: 60000 milliseconds (60 seconds)
func (*ChiMuxModule) RequiresServices ¶
func (m *ChiMuxModule) RequiresServices() []modular.ServiceDependency
RequiresServices declares services required by this module. The chimux module optionally depends on middleware providers. It will automatically discover and integrate with any modules that implement the MiddlewareProvider interface.
func (*ChiMuxModule) Route ¶
func (m *ChiMuxModule) Route(pattern string, fn func(chi.Router)) chi.Router
Chi Router methods - delegate to the underlying router
func (*ChiMuxModule) Routes ¶
func (m *ChiMuxModule) Routes() []chi.Route
Routes returns the router's route information (part of chi.Routes interface)
func (*ChiMuxModule) ServeHTTP ¶
func (m *ChiMuxModule) ServeHTTP(w http.ResponseWriter, r *http.Request)
ServeHTTP implements the http.Handler interface to properly handle base path prefixing
func (*ChiMuxModule) Start ¶
func (m *ChiMuxModule) Start(context.Context) error
Start performs startup logic for the module. This method loads tenant-specific configurations that may have been registered after module initialization. It's called after all modules have been initialized and are ready to start.
The startup process:
- Loads configurations for all registered tenants
- Applies tenant-specific CORS and routing settings
- Prepares the router for incoming requests
func (*ChiMuxModule) Stop ¶
func (m *ChiMuxModule) Stop(context.Context) error
Stop performs shutdown logic for the module. This method gracefully shuts down the router and cleans up resources. Note that the HTTP server itself is typically managed by a separate HTTP server module.
func (*ChiMuxModule) Trace ¶
func (m *ChiMuxModule) Trace(pattern string, h http.HandlerFunc)
type ChiRouterService ¶
type ChiRouterService interface { // ChiRouter returns the underlying chi.Router instance. // Use this when you need access to Chi's advanced features like // Route, Group, or other Chi-specific methods. ChiRouter() chi.Router }
ChiRouterService defines the interface for working with the Chi router. This interface provides direct access to the underlying Chi router instance for modules that need advanced Chi-specific functionality.
type Middleware ¶
Middleware is an alias for the Chi middleware handler function. This type represents a middleware function that can be applied to routes.
type MiddlewareProvider ¶
type MiddlewareProvider interface { // ProvideMiddleware returns a slice of middleware functions that should // be applied to the router. The middleware will be applied in the order // returned by this method. ProvideMiddleware() []Middleware }
MiddlewareProvider defines a service that provides middleware for the chimux router. Modules implementing this interface will have their middleware automatically discovered and applied to the router during initialization.
Example implementation:
type AuthModule struct{} func (a *AuthModule) ProvideMiddleware() []chimux.Middleware { return []chimux.Middleware{ authenticationMiddleware, authorizationMiddleware, } }
type Router ¶
type Router interface { BasicRouter chi.Router // Embed Chi's actual Router interface for full functionality }
Router extends BasicRouter with Chi's full router interface. This interface provides access to all Chi router functionality including Route groups, sub-routers, and advanced routing features.
Use this interface when you need Chi's advanced features like:
- Route groups with shared middleware
- Sub-routers with isolated middleware stacks
- Advanced routing patterns and matching
type RouterService ¶
type RouterService = BasicRouter
RouterService is an alias for BasicRouter. This provides a convenient service name for dependency injection when modules only need basic routing functionality.