76 lines
1.9 KiB
Go

package main
// @title Watch Party Backend API
// @version 1.0
// @description Backend API for watch-party app.
// @BasePath /
// @schemes http https
// @host localhost:8082
import (
"context"
"log"
"net/http"
"time"
_ "watch-party-backend/docs"
"watch-party-backend/internal/auth"
"watch-party-backend/internal/config"
"watch-party-backend/internal/db"
httpapi "watch-party-backend/internal/http"
"watch-party-backend/internal/repo"
"watch-party-backend/internal/service"
swaggerFiles "github.com/swaggo/files"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/gin-gonic/gin"
)
func main() {
// 1) config
cfg := config.Load()
gin.SetMode(cfg.GinMode)
// 2) DB pool
ctx := context.Background()
pool, err := db.NewPool(ctx, cfg.DB.DSN(), cfg.DB.MaxConns)
if err != nil {
log.Fatalf("db connect failed: %v", err)
}
defer pool.Close()
// 3) wiring
episodeRepo := repo.NewEpisodeRepo(pool)
episodeSvc := service.NewEpisodeService(episodeRepo)
var authClient auth.AuthClient
if cfg.Auth.Enabled {
v, err := auth.NewFirebaseAuth(ctx, cfg.Firebase)
if err != nil {
log.Fatalf("firebase auth init failed: %v", err)
}
authClient = v
log.Printf("auth enabled (project: %s)", cfg.Firebase.ProjectID)
} else {
log.Printf("auth disabled (AUTH_ENABLED=false)")
}
router := httpapi.NewRouter(episodeSvc, authClient, cfg.Auth.Enabled)
router.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
// 4) HTTP server with timeouts
s := &http.Server{
Addr: cfg.Addr,
Handler: router,
ReadTimeout: 10 * time.Second,
ReadHeaderTimeout: 5 * time.Second,
WriteTimeout: 30 * time.Second,
IdleTimeout: 60 * time.Second,
}
log.Printf("listening on %s (dsn: %s)", cfg.Addr, config.RedactDSN(cfg.DB.DSN()))
if err := s.ListenAndServe(); err != nil && err != http.ErrServerClosed {
log.Fatalf("server error: %v", err)
}
}