2022-09-07 23:34:37 +08:00
|
|
|
package router
|
|
|
|
|
|
|
|
import (
|
2023-07-15 16:19:49 +08:00
|
|
|
"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"
|
2023-07-14 21:47:11 +08:00
|
|
|
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
2022-09-07 23:34:37 +08:00
|
|
|
"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"
|
2023-07-15 16:19:49 +08:00
|
|
|
"github.com/samber/do"
|
2022-09-07 23:34:37 +08:00
|
|
|
swaggerFiles "github.com/swaggo/files"
|
|
|
|
"github.com/swaggo/gin-swagger"
|
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2023-07-15 16:19:49 +08:00
|
|
|
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()
|
2023-07-15 18:26:53 +08:00
|
|
|
srv.engine = srv.initRouters(conf, i)
|
2023-07-15 16:19:49 +08:00
|
|
|
|
|
|
|
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))
|
2022-09-07 23:34:37 +08:00
|
|
|
|
|
|
|
r := gin.New()
|
|
|
|
r.MaxMultipartMemory = 8 << 20
|
|
|
|
|
|
|
|
// Logger middleware and debug
|
2023-07-15 16:19:49 +08:00
|
|
|
if conf.Development {
|
2022-09-07 23:34:37 +08:00
|
|
|
// Gin's default logger is pretty enough
|
|
|
|
r.Use(gin.Logger())
|
|
|
|
r.Use(gin.Recovery())
|
|
|
|
// add prof
|
|
|
|
pprof.Register(r)
|
|
|
|
} else {
|
2023-07-15 16:19:49 +08:00
|
|
|
ginLog := s.logger.GetLogger("gin")
|
|
|
|
r.Use(ginZap.Ginzap(ginLog, time.RFC3339, false))
|
|
|
|
r.Use(ginZap.RecoveryWithZap(ginLog, true))
|
2022-09-07 23:34:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2023-07-15 16:19:49 +08:00
|
|
|
s.metric.SetLogPaths([]string{"/api"})
|
|
|
|
r.Use(s.metric.Handler())
|
2022-09-07 23:34:37 +08:00
|
|
|
|
|
|
|
// 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/")
|
2023-07-15 16:19:49 +08:00
|
|
|
s.setupApi(api, injector)
|
2022-09-07 23:34:37 +08:00
|
|
|
|
|
|
|
// 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
|
|
|
|
}
|