recipes2/internal/app/httpSrv/httpSrv.go

83 lines
2.1 KiB
Go

package httpsrv
import (
"context"
"log/slog"
"net/http"
"recipes/internal/config"
"recipes/internal/http-server/handlers/recipe"
recipeimage "recipes/internal/http-server/handlers/recipeImage"
"recipes/internal/http-server/handlers/recipes"
recipes_by_category "recipes/internal/http-server/handlers/recipesByCategory"
mwLogger "recipes/internal/http-server/middleware/logger"
"recipes/internal/lib/logger/sl"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
)
type App struct {
log *slog.Logger
router *chi.Mux
srv *http.Server
}
type Storage interface {
recipe.RecipeProvider
recipes.RecipesProvider
recipes_by_category.RecipesProvider
}
type MediaStorage interface {
recipeimage.ImageProvider
}
func New(log *slog.Logger, cfg *config.HTTPServerConfig, storage Storage, mediaStorage MediaStorage) *App {
// init router
router := chi.NewRouter()
// middlewares
router.Use(middleware.RequestID)
router.Use(mwLogger.New(log))
router.Use(middleware.Recoverer)
// routes
router.Get("/recipe", recipe.New(log, storage))
router.Get("/recipes_page", recipes.New(log, storage))
router.Get("/recipes_by_category", recipes_by_category.New(log, storage))
router.Get("/recipe_img", recipeimage.New(log, mediaStorage))
// server config
srv := &http.Server{
Addr: cfg.Address,
Handler: router,
ReadTimeout: cfg.Timeout,
WriteTimeout: cfg.Timeout,
IdleTimeout: cfg.IdleTimeout,
}
return &App{
log: log,
router: router,
srv: srv,
}
}
// MustRun starts http server or panic in case of error. Blocking function.
func (app *App) MustRun() {
const op = "app.httpSrv.Stop"
if err := app.srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
app.log.Error("failed to start server", slog.String("op", op), sl.Err(err))
panic(err)
}
app.log.Info("HTTP server stopped")
}
func (app *App) Stop() {
const op = "app.httpSrv.Stop"
shutdownCtx, shutdownCancel := context.WithTimeout(context.Background(), 30*time.Second)
err := app.srv.Shutdown(shutdownCtx)
if err != nil {
app.log.Error("failed to stop server", slog.String("op", op), sl.Err(err))
}
shutdownCancel()
}