The function of a module is to receive configuration to then turn it into action, i.e. take declarative input into business logic. At its core, Caddy is a configuration loading management system which comes with a logger, storage backend, configuration adapters, and an administration endpoint. This is evident in the structure of its configuration:
{
"admin": {},
"logging": {},
"storage": {•••},
"apps": {•••}
}
Every one of the aforementioned compoenents has modular parts within it. The native configuration language is JSON. The values within the apps object can be anything that is a Caddy app, which themselves are Caddy modules.
Caddy modules are implementations of interfaces. The most barebones Caddy module implements the interface caddy.Module, defined as:
type Module interface {
// This method indicates that the type is a Caddy
// module. The returned ModuleInfo must have both
// a name and a constructor function. This method
// must not have any side-effects.
CaddyModule() ModuleInfo
}
The type caddy.ModuleInfo is defined as:
type ModuleInfo struct {
// ID is the "full name" of the module. It
// must be unique and properly namespaced.
ID ModuleID
// New returns a pointer to a new, empty
// instance of the module's type. This
// method must not have any side-effects,
// and no other initialization should
// occur within it. Any initialization
// of the returned value should be done
// in a Provision() method (see the
// Provisioner interface).
New func() Module
}
type ModuleID string