package servecmd import ( "context" "flag" "fmt" "git.maronato.dev/maronato/goshort/cmd/shared" "git.maronato.dev/maronato/goshort/internal/config" "git.maronato.dev/maronato/goshort/internal/server" apiserver "git.maronato.dev/maronato/goshort/internal/server/api" healthcheckserver "git.maronato.dev/maronato/goshort/internal/server/healthcheck" servermiddleware "git.maronato.dev/maronato/goshort/internal/server/middleware" shortserver "git.maronato.dev/maronato/goshort/internal/server/short" staticssterver "git.maronato.dev/maronato/goshort/internal/server/static" shortservice "git.maronato.dev/maronato/goshort/internal/service/short" tokenservice "git.maronato.dev/maronato/goshort/internal/service/token" userservice "git.maronato.dev/maronato/goshort/internal/service/user" handlerutils "git.maronato.dev/maronato/goshort/internal/util/handler" "github.com/go-chi/chi/v5" "github.com/peterbourgon/ff/v3/ffcli" ) func New(cfg *config.Config) *ffcli.Command { // Create the flagset and register the flags. fs := flag.NewFlagSet("goshort serve", flag.ContinueOnError) shared.RegisterBaseFlags(fs, cfg) shared.RegisterServerFlags(fs, cfg) // Create the command and options cmd := shared.NewCommand(cfg, exec) opts := shared.NewSharedCmdOptions() // Return the ffcli command. return &ffcli.Command{ Name: "serve", ShortUsage: "goshort serve [flags]", ShortHelp: "Starts the API server with embedded frontend", FlagSet: fs, Exec: cmd.Exec, Options: opts, } } func exec(ctx context.Context, cfg *config.Config) error { // Create the new server server := server.NewServer(cfg) // Create services storage := shared.InitStorage(cfg) err := storage.Start(ctx) if err != nil { return fmt.Errorf("failed to start storage, %w", err) } defer storage.Stop(ctx) shortService := shortservice.NewShortService(storage) userService := userservice.NewUserService(cfg, storage) tokenService := tokenservice.NewTokenService(storage) // Create handlers apiHandler := apiserver.NewAPIHandler(shortService, userService, tokenService) shortHandler := shortserver.NewShortHandler(shortService) staticHandler := staticssterver.NewStaticHandler(cfg) healthcheckHandler := healthcheckserver.NewHealthcheckHandler() // Create routers apiRouter := apiserver.NewAPIRouter(apiHandler) shortRouter := shortserver.NewShortRouter(shortHandler) staticRouter := staticssterver.NewStaticRouter(staticHandler) healthcheckRouter := healthcheckserver.NewHealthcheckRouter(healthcheckHandler) // Create the root URL handler by chaining short and static routers chainedRouter := handlerutils.NewChainedHandler(shortRouter, staticRouter) // Configure app routes server.Mux.Route("/api", func(r chi.Router) { r.Use(servermiddleware.Auth(userService, tokenService)) r.Mount("/", apiRouter) }) server.Mux.Mount("/healthz", healthcheckRouter) server.Mux.Mount("/", chainedRouter) if err := server.ListenAndServe(ctx); err != nil { return fmt.Errorf("rrror during server execution, %w", err) } return nil }