stdfx provides standard functionality for golang apps built using uber-go/fx.
By using stdfx as an application starter you benefit from:
- common app interface
- cli arguments to adjust behavior
- config file discovery and parsing
- override config using environment variables
- builtin cobra subcommands like config or version
- configurable structured logging
See examples/everything to test and experience it in action.
A complete usage might look like this:
package main
import (
"go.uber.org/fx"
"github.com/choopm/stdfx"
"github.com/choopm/stdfx/configfx"
"github.com/choopm/stdfx/loggingfx/zerologfx"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
)
// version is provided by `-ldflags "-X main.version=1.0.0"`
var version string = "unknown"
func main() {
fx.New(
// logging
zerologfx.Module,
fx.WithLogger(zerologfx.ToFx),
fx.Decorate(zerologfx.Decorator[yourapp.Config]),
// viper configuration
fx.Provide(stdfx.ConfigFile[yourapp.Config]("yourapp")),
// cobra commands
fx.Provide(
stdfx.AutoRegister(stdfx.VersionCommand(version)),
stdfx.AutoRegister(stdfx.ConfigCommand[yourapp.Config]),
stdfx.AutoRegister(yourCobraCommand),
stdfx.AutoCommand, // add registered commands to root
),
// app start
fx.Invoke(stdfx.Unprivileged), // abort when being run as root
fx.Invoke(stdfx.Commander), // run root cobra command
).Run()
}
// yourCobraCommand returns a *cobra.Command to start the server from a ConfigProvider
func yourCobraCommand(
configProvider configfx.Provider[yourapp.Config],
logger *zerolog.Logger,
) *cobra.Command {
cmd := &cobra.Command{
Use: "server",
Short: "server starts the server",
RunE: func(cmd *cobra.Command, args []string) error {
// fetch the config
cfg, err := configProvider.Config()
if err != nil {
return err
}
// create server instance
server, err := yourapp.NewServer(cfg, logger)
if err != nil {
return err
}
// start server using context
return server.Start(cmd.Context())
},
}
return cmd
}
Open this project in Visual Studio Code and select to reopen it inside a dev container.
If you experience any issues, make sure your IDE supports dev containers: https://code.visualstudio.com/docs/devcontainers/containers
This project uses task.
Run task --list
to list all available tasks.