package app import ( "context" "github.com/gin-gonic/gin" log "github.com/sirupsen/logrus" "merch-parser-api/internal/interfaces" "merch-parser-api/internal/shared" "net/http" "time" ) type App struct { address string apiPrefix string modules []interfaces.Module routerHandler interfaces.Router router *gin.Engine } type Deps struct { Host string Port string ApiPrefix string Modules []interfaces.Module RouterHandler interfaces.Router } func NewApp(deps Deps) *App { app := &App{ address: deps.Host + ":" + deps.Port, apiPrefix: deps.ApiPrefix, routerHandler: deps.RouterHandler, modules: deps.Modules, } app.router = app.routerHandler.Set() apiRoutes := app.router.Group(app.apiPrefix) apiRoutes.GET("/", func(c *gin.Context) { c.String(http.StatusOK, "API is ready") }) var excludeRoutes []shared.ExcludeRoute for _, m := range app.modules { if hasRoutes, ok := m.(interfaces.ModuleRoutes); ok { hasRoutes.RegisterRoutes(apiRoutes) excludeRoutes = append(excludeRoutes, hasRoutes.ExcludeRoutes()...) } } app.routerHandler.ExcludeRoutes(excludeRoutes) return app } func (a *App) Run(ctx context.Context) error { server := &http.Server{ Addr: a.address, Handler: a.router, } serverErr := make(chan error, 1) go func() { log.Info("Starting server on: ", a.address) serverErr <- server.ListenAndServe() }() select { case <-ctx.Done(): log.Info("Shutting down server") shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() return server.Shutdown(shutdownCtx) case err := <-serverErr: return err } }