chimux

package module
v1.0.6 Latest Latest
Warning

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

Go to latest
Published: Jun 27, 2025 License: MIT Imports: 10 Imported by: 1

README

chimux Module

A module for the Modular framework.

Overview

The chimux module provides a powerful HTTP router and middleware system for Modular applications by integrating the popular go-chi router. This module allows Modular applications to easily set up and configure HTTP routing with middleware support, all while maintaining the modular architecture and configuration management that Modular offers.

Features

  • Full integration of go-chi router within the Modular framework
  • Configurable middleware stack with pre-defined middleware options
  • Easy route registration through service interfaces
  • Support for RESTful resource patterns
  • Mount handlers at specific path prefixes
  • Configurable CORS settings
  • Timeout management for request handling
  • Base path configuration for all routes

Installation

go get github.com/GoCodeAlone/modular/modules/chimux@v1.0.0

Usage

package main

import (
	"github.com/GoCodeAlone/modular"
	"github.com/GoCodeAlone/modular/modules/chimux"
	"log/slog"
	"net/http"
	"os"
)

func main() {
	// Create a new application
	app := modular.NewStdApplication(
		modular.NewStdConfigProvider(&AppConfig{}),
		slog.New(slog.NewTextHandler(os.Stdout, nil)),
	)

	// Register the chimux module
	app.RegisterModule(chimux.NewChimuxModule())
	
	// Register your API module that will use the router
	app.RegisterModule(NewAPIModule())

	// Run the application
	if err := app.Run(); err != nil {
		app.Logger().Error("Application error", "error", err)
		os.Exit(1)
	}
}

// APIModule that uses the chimux router
type APIModule struct {
	router chimux.RouterService
}

func NewAPIModule() modular.Module {
	return &APIModule{}
}

func (m *APIModule) Name() string {
	return "api"
}

func (m *APIModule) Dependencies() []string {
	return []string{"chimux"} // Depend on chimux module
}

func (m *APIModule) RequiresServices() []modular.ServiceDependency {
	return []modular.ServiceDependency{
		{
			Name:     "chimux.router",
			Required: true,
		},
	}
}

func (m *APIModule) Init(app modular.Application) error {
	// Get the router service
	if err := app.GetService("chimux.router", &m.router); err != nil {
		return err
	}
	
	// Register routes
	m.router.Get("/api/health", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`{"status":"ok"}`))
	})
	
	m.router.Route("/api/users", func(r chimux.Router) {
		r.Get("/", m.listUsers)
		r.Post("/", m.createUser)
		r.Route("/{id}", func(r chimux.Router) {
			r.Get("/", m.getUser)
			r.Put("/", m.updateUser)
			r.Delete("/", m.deleteUser)
		})
	})
	
	return nil
}

// Other required module methods...

Configuration

The chimux module supports the following configuration options:

Option Type Required Default Description
AllowedOrigins []string No ["*"] List of allowed origins for CORS requests.
AllowedMethods []string No ["GET","POST","PUT","DELETE","OPTIONS"] List of allowed HTTP methods.
AllowedHeaders []string No ["Origin","Accept","Content-Type","X-Requested-With","Authorization"] List of allowed request headers.
AllowCredentials bool No false Allow credentials in CORS requests.
MaxAge int No 300 Maximum age for CORS preflight cache in seconds.
Timeout int No 60000 Default request timeout in milliseconds.
BasePath string No - A base path prefix for all routes registered through this module.
EnabledMiddleware []string No ["Heartbeat","RequestID","RealIP","Logger","Recoverer"] List of middleware to enable by default.
Example Configuration
# config.yaml
chimux:
  allowedorigins: ["*"]
  allowedmethods: ["GET","POST","PUT","DELETE","OPTIONS"]
  allowedheaders: ["Origin","Accept","Content-Type","X-Requested-With","Authorization"]
  allowcredentials: false
  maxage: 300
  timeout: 60000
  basepath: "/api"
  enabledmiddleware: ["Heartbeat", "RequestID", "RealIP", "Logger", "Recoverer"]

Middleware Configuration

chimux supports two approaches for configuring middleware:

1. Configuration-based middleware

Define which built-in middleware to enable through configuration:

chimux:
  enabledmiddleware: 
    - "RequestID"
    - "RealIP"
    - "Logger"
    - "Recoverer"
    - "StripSlashes"
    - "Timeout"
2. Programmatic middleware registration

For custom middleware, you can register it during module initialization or by implementing the MiddlewareProvider interface:

// Custom middleware provider module
type AuthMiddlewareModule struct {
    // module implementation
}

func (m *AuthMiddlewareModule) ProvidesServices() []modular.ServiceProvider {
    return []modular.ServiceProvider{
        {
            Name: "auth.middleware",
            Instance: chimux.MiddlewareProvider(func() []chimux.Middleware {
                return []chimux.Middleware{
                    m.jwtAuthMiddleware,
                    m.roleCheckerMiddleware,
                }
            }),
        },
    }
}

// Define your custom middleware
func (m *AuthMiddlewareModule) jwtAuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // JWT authentication logic
        next.ServeHTTP(w, r)
    })
}

The chimux module will automatically discover and use any registered MiddlewareProvider services using interface-based service matching.

Advanced Usage

Adding custom middleware to specific routes
func (m *APIModule) Init(app modular.Application) error {
    // Get the router service
    err := app.GetService("chimux.router", &m.router)
    if err != nil {
        return err
    }
    
    // Create middleware
    adminOnly := func(next http.Handler) http.Handler {
        return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            // Check if user is admin
            if isAdmin := checkAdmin(r); !isAdmin {
                http.Error(w, "Unauthorized", http.StatusUnauthorized)
                return
            }
            next.ServeHTTP(w, r)
        })
    }
    
    // Apply middleware to specific routes
    m.router.Route("/admin", func(r chimux.Router) {
        r.Use(adminOnly)
        r.Get("/dashboard", m.adminDashboard)
        r.Post("/users", m.adminCreateUser)
    })
    
    return nil
}
Accessing the underlying chi.Router

If needed, you can access the underlying chi.Router for advanced functionality:

func (m *APIModule) Init(app modular.Application) error {
    var router chimux.ChiRouterService
    if err := app.GetService("chimux.router", &router); err != nil {
        return err
    }
    
    // Access the underlying chi.Router
    chiRouter := router.ChiRouter()
    
    // Use chi-specific features
    chiRouter.Mount("/legacy", legacyHandler)
    
    return nil
}

License

MIT License

Documentation

Index

Constants

View Source
const ModuleName = "chimux"

ModuleName is the name of this module

View Source
const ServiceName = "chimux.router"

ServiceName is the name of the service provided by this module (the chi router)

Variables

View Source
var (
	// ErrRequiresTenantApplication is returned when the module is initialized with a non-tenant application
	ErrRequiresTenantApplication = errors.New("chimux module requires a TenantApplication")
)

Error definitions

Functions

func NewChiMuxModule

func NewChiMuxModule() modular.Module

NewChiMuxModule creates a new instance of the chimux module

Types

type BasicRouter added in v1.0.2

type BasicRouter interface {
	// HTTP method handlers
	Get(pattern string, handler http.HandlerFunc)
	Post(pattern string, handler http.HandlerFunc)
	Put(pattern string, handler http.HandlerFunc)
	Delete(pattern string, handler http.HandlerFunc)
	Patch(pattern string, handler http.HandlerFunc)
	Head(pattern string, handler http.HandlerFunc)
	Options(pattern string, handler http.HandlerFunc)

	// Generic handlers
	Handle(pattern string, handler http.Handler)
	HandleFunc(pattern string, handler http.HandlerFunc)

	// Mounting and middleware
	Mount(pattern string, handler http.Handler)
	Use(middlewares ...func(http.Handler) http.Handler)

	// HTTP handler
	ServeHTTP(w http.ResponseWriter, r *http.Request)
}

BasicRouter defines the essential router interface that most modules need This interface avoids the Route/Group methods that are problematic for interface abstraction

type ChiMuxConfig

type ChiMuxConfig struct {
	AllowedOrigins []string `yaml:"allowed_origins" default:"[\"*\"]" desc:"List of allowed origins for CORS requests." env:"ALLOWED_ORIGINS"` // List of allowed origins for CORS requests.
	AllowedMethods []string ``                                                                                                                 // List of allowed HTTP methods.
	/* 141-byte string literal not displayed */
	AllowedHeaders []string `` // List of allowed request headers.
	/* 174-byte string literal not displayed */
	AllowCredentials bool   `yaml:"allow_credentials" default:"false" desc:"Allow credentials in CORS requests." env:"ALLOW_CREDENTIALS"` // Allow credentials in CORS requests.
	MaxAge           int    `yaml:"max_age" default:"300" desc:"Maximum age for CORS preflight cache in seconds." env:"MAX_AGE"`          // Maximum age for CORS preflight cache in seconds.
	Timeout          int    `yaml:"timeout" default:"60000" desc:"Default request timeout." env:"TIMEOUT"`                                // Default request timeout.
	BasePath         string `yaml:"basepath" desc:"A base path prefix for all routes registered through this module." env:"BASE_PATH"`    // A base path prefix for all routes registered through this module.
}

ChiMuxConfig holds the configuration for the chimux module

func (*ChiMuxConfig) Validate

func (c *ChiMuxConfig) Validate() error

Validate implements the modular.ConfigValidator interface

type ChiMuxModule

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

ChiMuxModule represents the chimux module

func (*ChiMuxModule) ChiRouter

func (m *ChiMuxModule) ChiRouter() chi.Router

ChiRouter returns the underlying chi.Router instance

func (*ChiMuxModule) Connect added in v1.0.2

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

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

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 base config if no specific tenant config is found.

func (*ChiMuxModule) Group added in v1.0.2

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 module

func (*ChiMuxModule) Match added in v1.0.2

func (m *ChiMuxModule) Match(rctx *chi.Context, method, path string) bool

func (*ChiMuxModule) Method added in v1.0.2

func (m *ChiMuxModule) Method(method, pattern string, h http.Handler)

func (*ChiMuxModule) MethodFunc added in v1.0.2

func (m *ChiMuxModule) MethodFunc(method, pattern string, h http.HandlerFunc)

func (*ChiMuxModule) MethodNotAllowed added in v1.0.2

func (m *ChiMuxModule) MethodNotAllowed(h http.HandlerFunc)

func (*ChiMuxModule) Middlewares added in v1.0.2

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 name of the module

func (*ChiMuxModule) NotFound added in v1.0.2

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

func (*ChiMuxModule) OnTenantRemoved

func (m *ChiMuxModule) OnTenantRemoved(tenantID modular.TenantID)

OnTenantRemoved is called when a tenant is removed

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

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

func (*ChiMuxModule) RequiresServices

func (m *ChiMuxModule) RequiresServices() []modular.ServiceDependency

RequiresServices declares services required by this module

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

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

func (*ChiMuxModule) Stop

func (m *ChiMuxModule) Stop(context.Context) error

Stop performs shutdown logic for the module

func (*ChiMuxModule) Trace added in v1.0.2

func (m *ChiMuxModule) Trace(pattern string, h http.HandlerFunc)

func (*ChiMuxModule) Use

func (m *ChiMuxModule) Use(middlewares ...func(http.Handler) http.Handler)

Use appends middleware to the chain

func (*ChiMuxModule) With added in v1.0.2

func (m *ChiMuxModule) With(middlewares ...func(http.Handler) http.Handler) chi.Router

type ChiRouterService

type ChiRouterService interface {
	// Direct access to the underlying chi router
	ChiRouter() chi.Router
}

ChiRouterService defines the interface for working with the Chi router

type Middleware

type Middleware func(http.Handler) http.Handler

Middleware is an alias for the chi middleware handler function

type MiddlewareProvider

type MiddlewareProvider interface {
	ProvideMiddleware() []Middleware
}

MiddlewareProvider defines a service that provides middleware for the chimux router

type Router

type Router interface {
	BasicRouter
	chi.Router // Embed Chi's actual Router interface
}

Router extends BasicRouter with Chi's actual interface This allows modules that need Route/Group to access them directly

type RouterService

type RouterService = BasicRouter

RouterService is an alias for BasicRouter for modules that don't need Route/Group

Jump to

Keyboard shortcuts

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