package router import ( "git.0x7f.app/WOJ/woj-server/internal/misc/config" "git.0x7f.app/WOJ/woj-server/internal/misc/log" "git.0x7f.app/WOJ/woj-server/internal/model" "git.0x7f.app/WOJ/woj-server/internal/web/metrics" _ "git.0x7f.app/WOJ/woj-server/internal/web/router/docs" "git.0x7f.app/WOJ/woj-server/pkg/utils" "github.com/gin-contrib/cors" "github.com/gin-contrib/pprof" ginZap "github.com/gin-contrib/zap" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/samber/do" swaggerFiles "github.com/swaggo/files" "github.com/swaggo/gin-swagger" "net/http" "time" ) var _ Service = (*service)(nil) type Service interface { GetRouter() *gin.Engine HealthCheck() error } func NewService(i *do.Injector) (Service, error) { srv := &service{} srv.metric = do.MustInvoke[metrics.Service](i) srv.logger = do.MustInvoke[log.Service](i) conf := do.MustInvoke[config.Service](i).GetConfig() srv.engine = srv.initRouters(conf, i) return srv, srv.err } type service struct { metric metrics.Service logger log.Service engine *gin.Engine err error } func (s *service) GetRouter() *gin.Engine { return s.engine } func (s *service) HealthCheck() error { return s.err } func (s *service) initRouters(conf *model.Config, injector *do.Injector) *gin.Engine { gin.SetMode(utils.If(conf.Development, gin.DebugMode, gin.ReleaseMode)) r := gin.New() r.MaxMultipartMemory = 8 << 20 // Logger middleware and debug if conf.Development { // Gin's default logger is pretty enough r.Use(gin.Logger()) r.Use(gin.Recovery()) // add prof pprof.Register(r) } else { ginLog := s.logger.GetLogger("gin") r.Use(ginZap.Ginzap(ginLog, time.RFC3339, false)) r.Use(ginZap.RecoveryWithZap(ginLog, true)) } // CORS middleware r.Use(cors.New(cors.Config{ AllowAllOrigins: true, AllowMethods: []string{"GET", "POST", "PUT", "OPTIONS"}, AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"}, AllowCredentials: true, })) // Prometheus middleware s.metric.SetLogPaths([]string{"/api"}) r.Use(s.metric.Handler()) // metrics r.GET("/metrics", gin.WrapH(promhttp.Handler())) // swagger r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) // health r.GET("/health", func(c *gin.Context) { resp := &struct { Timestamp time.Time `json:"timestamp"` Status string `json:"status"` }{ Timestamp: time.Now(), Status: "ok", } c.JSON(http.StatusOK, resp) }) // api api := r.Group("/api/") s.setupApi(api, injector) // static files r.Static("/static", "./resource/frontend/static") r.StaticFile("/", "./resource/frontend/index.html") r.NoRoute(func(c *gin.Context) { c.File("./resource/frontend/index.html") }) return r }