package cmd import ( "net/http" "github.com/justinas/alice" "github.com/rs/zerolog" "orus.io/orus-io/go-orusapi" "orus.io/orus-io/go-orusapi/auth" ) //nolint:lll type ServeCmd[E any] struct { Server *orusapi.Server AutoMigrate bool `long:"auto-migrate" ini-name:"auto-migrate" description:"Automaticaly migrate the database if necessary" env:"AUTOMIGRATE"` program *Program[E] } type serveAPI struct { name string handler http.Handler } func (api *serveAPI) Name() string { return api.name } func (api *serveAPI) Handler() http.Handler { return api.handler } func (api *serveAPI) PreServerShutdown() { } func (api *serveAPI) ServerShutdown() { } func (cmd *ServeCmd[E]) Execute([]string) error { if err := cmd.program.TokenOptions.EnsureSecret(); err != nil { return err } if err := cmd.program.EnsureDB(cmd.AutoMigrate); err != nil { return err } defer cmd.program.CloseDB() stack := alice.New(orusapi.LogStack(cmd.program.Logger, zerolog.WarnLevel)...) for _, middleware := range cmd.program.authMiddlewares { m, err := middleware.Middleware(cmd.program) if err != nil { return err } stack = stack.Append(m) } stack = stack.Append(auth.LogUserHandler) for _, middleware := range cmd.program.middlewares { m, err := middleware.Middleware(cmd.program) if err != nil { return err } stack = stack.Append(m) } handler := stack.Then(cmd.program.setupHandler(cmd.program)) cmd.Server.SetLog(cmd.program.Logger) cmd.Server.Environment = cmd.program.InfoOptions.Environment cmd.Server.SetAPI(&serveAPI{ name: cmd.program.Parser.Name, handler: handler, }) defer func() { if err := cmd.Server.Shutdown(); err != nil { cmd.program.Logger.Err(err).Msg("error shutting down the server") } }() if err := cmd.Server.Serve(); err != nil { return err } return nil } func SetupServeCmd[E any](program *Program[E]) *ServeCmd[E] { cmd := ServeCmd[E]{ program: program, Server: orusapi.NewServer(nil), } serve, err := program.Parser.AddCommand("serve", "Serves the API", "", &cmd) if err != nil { program.Logger.Fatal().Msg(err.Error()) } serve.EnvNamespace = "SERVE" return &cmd }