Understanding Caddy’s module namespace organization and naming conventions
Caddy uses a hierarchical namespace system to organize modules. Understanding this system is essential for creating modules that integrate properly with Caddy’s architecture.
// Namespace returns the namespace portion of a module IDfunc (id ModuleID) Namespace() string { lastDot := strings.LastIndex(string(id), ".") if lastDot < 0 { return "" // Top-level module (app) } return string(id)[:lastDot]}// Name returns the Name (last element) of a module IDfunc (id ModuleID) Name() string { if id == "" { return "" } parts := strings.Split(string(id), ".") return parts[len(parts)-1]}
http.matchers.host Match by hostnamehttp.matchers.path Match by pathhttp.matchers.method Match by HTTP methodhttp.matchers.header Match by headershttp.matchers.query Match by query parametershttp.matchers.remote_ip Match by client IP
caddy.logging.writers.file File outputcaddy.logging.writers.stderr Standard errorcaddy.logging.writers.stdout Standard outputcaddy.logging.encoders.json JSON log formatcaddy.logging.encoders.console Console log format
// GetModules returns all modules in the given scope/namespacefunc GetModules(scope string) []ModuleInfo
Example usage:
// Get all HTTP handlershandlers := caddy.GetModules("http.handlers")for _, handler := range handlers { fmt.Println(handler.ID)}// Get all top-level appsapps := caddy.GetModules("")
Partial scopes are not matched. "http.handlers" will not match "http.handlers.foo.bar".
// GetModule returns module information from its IDfunc GetModule(name string) (ModuleInfo, error) { modulesMu.RLock() defer modulesMu.RUnlock() m, ok := modules[name] if !ok { return ModuleInfo{}, fmt.Errorf("module not registered: %s", name) } return m, nil}