woj-server/internal/web/router/router.go

153 lines
3.5 KiB
Go
Raw Normal View History

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"
sentrygin "github.com/getsentry/sentry-go/gin"
2022-09-07 23:34:37 +08:00
"github.com/gin-contrib/cors"
"github.com/gin-contrib/pprof"
2024-03-16 17:16:02 +08:00
"github.com/gin-contrib/static"
2022-09-07 23:34:37 +08:00
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 {
logger log.Service
engine *gin.Engine
2024-01-03 00:55:41 +08:00
metric metrics.Service
2024-01-05 00:57:43 +08:00
err error
2023-07-15 16:19:49 +08:00
}
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 {
2023-12-22 15:23:24 +08:00
gin.SetMode(utils.If[string](conf.Development, gin.DebugMode, gin.ReleaseMode))
2022-09-07 23:34:37 +08:00
r := gin.New()
// +--------------+
// |Configurations|
// +--------------+
if conf.WebServer.TrustedPlatform != "" {
// Extract Origin IP
r.TrustedPlatform = conf.WebServer.TrustedPlatform
}
2023-12-25 22:32:15 +08:00
// +-----------+
// |Middlewares|
// +-----------+
2022-09-07 23:34:37 +08:00
// 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
}
2024-01-06 21:05:54 +08:00
// Sentry middleware
r.Use(sentrygin.New(sentrygin.Options{Repanic: 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"},
2023-12-21 17:08:53 +08:00
AllowHeaders: []string{"Authorization", "Origin", "Content-Length", "Content-Type"},
2022-09-07 23:34:37 +08:00
AllowCredentials: true,
}))
// Prometheus middleware
2023-07-15 16:19:49 +08:00
s.metric.SetLogPaths([]string{"/api"})
s.metric.SetIgnorePaths([]string{"/api/v1/oauth/callback"})
2023-07-15 16:19:49 +08:00
r.Use(s.metric.Handler())
2022-09-07 23:34:37 +08:00
2023-12-25 22:32:15 +08:00
// +------+
// |Routes|
// +------+
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) {
var err bool
for _, v := range injector.HealthCheck() {
if v != nil {
err = true
break
}
}
2022-09-07 23:34:37 +08:00
resp := &struct {
Timestamp time.Time `json:"timestamp"`
Status string `json:"status"`
}{
Timestamp: time.Now(),
Status: utils.If(err, "unhealthy", "healthy"),
2022-09-07 23:34:37 +08:00
}
c.JSON(utils.If(err, http.StatusServiceUnavailable, http.StatusOK), resp)
2022-09-07 23:34:37 +08:00
})
// 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
2024-04-28 01:03:53 +08:00
// do not allow crawling
r.GET("/robots.txt", func(c *gin.Context) {
c.String(http.StatusOK, "User-agent: *\nDisallow: /")
})
// static files
r.Use(static.Serve("/", static.LocalFile("./resource/frontend", true)))
2023-12-25 22:32:15 +08:00
// fallback to frontend
2023-12-23 17:34:45 +08:00
r.NoRoute(func(c *gin.Context) {
c.File("./resource/frontend/index.html")
})
2022-09-07 23:34:37 +08:00
return r
}