Auto-configure
Normally you edit configure_*.go by hand to attach each handler. The
auto-configure example takes a different route: generate with
--implementation-package, point it at a package you write, and the generator
emits the wiring for you. Every operation is routed to a method on your
implementation — no hand-editing of a configure file.
Tip
Source: auto-configure/.
Generated with swagger generate server --name AToDoListApplication --spec ./swagger.yml --implementation-package github.com/go-swagger/examples/auto-configure/implementation --principal any.
The generated contract
Instead of a configure_*.go, the generator produces
auto_configure_*.go. It declares the Handler interface your package must
satisfy, and binds a package-level Impl to your constructor via
implementation.New():
var Impl Handler = implementation.New()
// Handler handles all api server backend configurations and requests
type Handler interface {
Authable
Configurable
TodosHandler
}
// Configurable handles all server configurations
type Configurable interface {
ConfigureFlags(api *operations.AToDoListApplicationAPI)
ConfigureTLS(tlsConfig *tls.Config)
ConfigureServer(s *http.Server, scheme, addr string)
CustomConfigure(api *operations.AToDoListApplicationAPI)
SetupMiddlewares(handler http.Handler) http.Handler
SetupGlobalMiddleware(handler http.Handler) http.Handler
}
// Authable handles server authentication
type Authable interface {
// Applies when the "x-todolist-token" header is set
KeyAuth(token string) (any, error)
}
// TodosHandler
type TodosHandler interface {
AddOne(params todos.AddOneParams, principal any) middleware.Responder
DestroyOne(params todos.DestroyOneParams, principal any) middleware.Responder
FindTodos(params todos.FindTodosParams, principal any) middleware.Responder
UpdateOne(params todos.UpdateOneParams, principal any) middleware.Responder
}Full source: auto-configure/restapi/auto_configure_a_to_do_list_application.go
Each generated handler then simply delegates to that Impl:
api.TodosAddOneHandler = todos.AddOneHandlerFunc(func(params todos.AddOneParams, principal any) middleware.Responder {
return Impl.AddOne(params, principal)
})Full source: auto-configure/restapi/auto_configure_a_to_do_list_application.go
Your implementation package
You write a package that implements Handler. This is ordinary hand-written code
— nothing generated — so it’s the natural home for your business logic. Here’s
the AddOne method backing the in-memory store:
func (i *TodosHandlerImpl) AddOne(params todos.AddOneParams, principal any) middleware.Responder {
_ = principal
i.lock.Lock()
defer i.lock.Unlock()
newItem := params.Body
if newItem == nil {
return todos.NewAddOneDefault(http.StatusBadRequest).
WithPayload(&models.Error{
Code: http.StatusBadRequest,
Message: &[]string{"Item Body is nil"}[0],
})
}
// assign new id
newItem.ID = i.idx
i.idx++
i.items[newItem.ID] = newItem
return todos.NewAddOneCreated().WithPayload(newItem)
}Full source: auto-configure/implementation/todos_impl.go
The example splits the interface across small types — TodosHandlerImpl,
ConfigureImpl, AuthImpl — composed by a single HandlerImpl that New()
returns. That keeps handlers, server configuration, and authentication in
separate files while still satisfying the one generated Handler interface.
When to use it
Auto-configure shines when you regenerate often and don’t want a hand-edited
configure_*.go in the loop: your implementation lives entirely in a package you
own, and regeneration only ever touches the generated wiring. It’s also a clean
way to keep the transport-facing glue separate from your domain code.
Related
- Todo list server — the conventional hand-wired
configure_*.go. - Custom error handling — centralized error responses.