As mentioned in the index page of this chapter, modules implement the caddy.Module interface, which is 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
This makes the simplest way to impelement a (rather non-functional) module is:
type MyModule struct{}
func(MyModule) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: "namespace.of.my_module",
New: func() caddy.Module {
new(MyModule)
},
}
}
// optional but recommended
var _ caddy.Module = (*MyModule)(nil)
However, you must also tell Caddy about the module, which is typically done by registering it in an init() func as such:
import "github.com/caddyserver/caddy/v2"
func init(){
caddy.RegisterModule(MyModule{})
}